Documentation
¶
Index ¶
- Constants
- Variables
- func BaselineExtract(raw string) (extractedState string, extractedPostcode string)
- func BatchParseSeq(inputs []string) iter.Seq2[int, Result[Postcode]]
- func ClearDiskCache() error
- func Coordinates(raw string) (lat, lng float64, err error)
- func DefaultCachePath() string
- func ExportBuildingsJSON(w io.Writer) error
- func GetCachePath() string
- func GetCacheStats() (int, string)
- func GoogleMapsURL(raw string) (string, error)
- func IsValid(raw string) bool
- func LoadBuildingsCSV(r io.Reader) (int, error)
- func LoadBuildingsJSON(r io.Reader) (int, error)
- func LoadDiskCache() error
- func ParseSeq(inputs []string) iter.Seq2[Postcode, error]
- func RegisterKnownBuilding(rec BuildingRecord)
- func SaveDiskCache() error
- func SetCachePath(path string) error
- func Validate(raw string) error
- type APIError
- type AdministrativeAddress
- type AgentDispatcher
- type AgentGuardConfig
- type AgentGuardMetrics
- type AssembledPostcode
- type AutocompleteResponse
- type AutocompleteSuggestion
- type BuildingRecord
- type Cache
- type ChainGeocoder
- type Client
- func (c *Client) AgentMetrics() AgentGuardMetrics
- func (c *Client) Assemble(ctx context.Context, segs Segments) (*AssembledPostcode, error)
- func (c *Client) Autocomplete(ctx context.Context, query string) (*AutocompleteResponse, error)
- func (c *Client) Disassemble(ctx context.Context, code string) (*Segments, error)
- func (c *Client) Health(ctx context.Context) error
- func (c *Client) Lookup(ctx context.Context, code string, level LookupLevel) (*LookupResponse, error)
- func (c *Client) Nearby(ctx context.Context, params NearbyParams) (*NearbyResponse, error)
- func (c *Client) NearbyPostcode(ctx context.Context, code string, radiusM float64) (*NearbyResponse, error)
- func (c *Client) RateLimit() *RateLimitInfo
- func (c *Client) ReferenceAreas(ctx context.Context, state, lga, district string) ([]NamedCode, error)
- func (c *Client) ReferenceDistricts(ctx context.Context, state, lga string) ([]NamedCode, error)
- func (c *Client) ReferenceLGAs(ctx context.Context, state string) ([]NamedCode, error)
- func (c *Client) ReferenceStates(ctx context.Context) ([]NamedCode, error)
- func (c *Client) ResolveLocation(ctx context.Context, code string) (*Location, error)
- func (c *Client) Reverse(ctx context.Context, params ReverseParams) (*ReverseResponse, error)
- func (c *Client) ReverseCoordinates(ctx context.Context, lat, lng, maxDistanceM float64) (*ReverseResponse, error)
- type ClientOption
- func WithAPIKey(key string) ClientOption
- func WithAgentGuard(cfg AgentGuardConfig) ClientOption
- func WithBaseTransport(rt http.RoundTripper) ClientOption
- func WithBaseURL(customURL string) ClientOption
- func WithCache(cache Cache) ClientOption
- func WithDefaultCache() ClientOption
- func WithGeocoder(g Geocoder) ClientOption
- func WithGoogleMapsKey(key string) ClientOption
- func WithRateLimitRetry(enabled bool, maxDelay time.Duration) ClientOption
- func WithRetryConfig(cfg RetryConfig) ClientOption
- func WithTelemetry(t Telemetry) ClientOption
- func WithTimeout(d time.Duration) ClientOption
- func WithTransport(rt http.RoundTripper) ClientOption
- type DiagnosticReport
- type EvalResult
- type GeneratorOptions
- type Geocoder
- type GoogleMapsGeocoder
- type LGARecord
- type Location
- type LookupLevel
- type LookupResponse
- type MCPOption
- type MCPServer
- type MemoryCache
- type MetricsRecorder
- type NamedCode
- type NearbyParams
- type NearbyResponse
- type NearbyUnit
- type NominatimGeocoder
- type PointGeometry
- type Postcode
- func (p Postcode) AppendText(b []byte) ([]byte, error)
- func (p Postcode) Area() string
- func (p Postcode) BuildingUnit() string
- func (p Postcode) Compact() string
- func (p Postcode) Coordinates() (lat, lng float64)
- func (p Postcode) District() string
- func (p Postcode) Formatted() string
- func (p Postcode) GoogleMapsURL() string
- func (p Postcode) IsZero() bool
- func (p Postcode) LGA() string
- func (p Postcode) Location() Location
- func (p Postcode) MarshalText() ([]byte, error)
- func (p Postcode) Raw() string
- func (p Postcode) State() string
- func (p Postcode) String() string
- func (p *Postcode) UnmarshalText(text []byte) error
- type Precision
- type RateLimitInfo
- type RecentHouseAddress
- type Result
- type RetryConfig
- type RetryTransport
- type ReverseParams
- type ReverseResponse
- type SegmentDiagnosis
- type Segments
- type Span
- type StateRecord
- type SyntheticAddress
- type Telemetry
- type ToolDef
- type Tracer
- type ValidationError
Constants ¶
const ( // MCPProtocolVersionLatest is the modern stateless protocol revision (SEP-2575). MCPProtocolVersionLatest = "2026-07-28" // MCPProtocolVersion2025 is the intermediate 2025 specification revision. MCPProtocolVersion2025 = "2025-11-25" // MCPProtocolVersionLegacy is the original initialization-based protocol revision. MCPProtocolVersionLegacy = "2024-11-05" MCPServerName = "postcode-mcp" MCPServerVersion = "1.0.0" )
MCP Protocol Revisions & Server Metadata per MCP 2026-07-28 Specification
const (
DefaultBaseURL = "https://api.postcode.gov.ng"
)
Variables ¶
var ( ErrInvalidLength = errors.New("postcode: invalid length, must be exactly 11 alphanumeric characters") ErrInvalidFormat = errors.New("postcode: invalid format structure") )
var ErrAgentBudgetExceeded = errors.New("postcode: agent call budget exceeded for session")
ErrAgentBudgetExceeded is returned when an autonomous agent reaches its configured call ceiling.
var ErrUnknownState = errors.New("postcode: unknown nigerian state code")
ErrUnknownState indicates that a postcode has a state prefix not recognized in the Nigerian state registry.
var MCPSupportedVersions = []string{ MCPProtocolVersionLatest, MCPProtocolVersion2025, MCPProtocolVersionLegacy, }
MCPSupportedVersions lists all supported protocol revisions in order of preference.
var NigerianStates = map[string]StateRecord{
"AB": {Code: "AB", Name: "Abia", Capital: "Umuahia", Latitude: 5.5320, Longitude: 7.4860, Zone: "SOUTH EAST"},
"AD": {Code: "AD", Name: "Adamawa", Capital: "Yola", Latitude: 9.2094, Longitude: 12.4818, Zone: "NORTH EAST"},
"AK": {Code: "AK", Name: "Akwa Ibom", Capital: "Uyo", Latitude: 5.0377, Longitude: 7.9128, Zone: "SOUTH SOUTH"},
"AN": {Code: "AN", Name: "Anambra", Capital: "Awka", Latitude: 6.2209, Longitude: 7.0670, Zone: "SOUTH EAST"},
"BA": {Code: "BA", Name: "Bauchi", Capital: "Bauchi", Latitude: 10.3158, Longitude: 9.8442, Zone: "NORTH EAST"},
"BY": {Code: "BY", Name: "Bayelsa", Capital: "Yenagoa", Latitude: 4.9267, Longitude: 6.2676, Zone: "SOUTH SOUTH"},
"BN": {Code: "BN", Name: "Benue", Capital: "Makurdi", Latitude: 7.7304, Longitude: 8.5211, Zone: "NORTH CENTRAL"},
"BO": {Code: "BO", Name: "Borno", Capital: "Maiduguri", Latitude: 11.8333, Longitude: 13.1500, Zone: "NORTH EAST"},
"CR": {Code: "CR", Name: "Cross River", Capital: "Calabar", Latitude: 4.9757, Longitude: 8.3417, Zone: "SOUTH SOUTH"},
"DE": {Code: "DE", Name: "Delta", Capital: "Asaba", Latitude: 6.1984, Longitude: 6.7329, Zone: "SOUTH SOUTH"},
"EB": {Code: "EB", Name: "Ebonyi", Capital: "Abakaliki", Latitude: 6.3249, Longitude: 8.1137, Zone: "SOUTH EAST"},
"ED": {Code: "ED", Name: "Edo", Capital: "Benin City", Latitude: 6.3350, Longitude: 5.6037, Zone: "SOUTH SOUTH"},
"EK": {Code: "EK", Name: "Ekiti", Capital: "Ado Ekiti", Latitude: 7.6211, Longitude: 5.2215, Zone: "SOUTH WEST"},
"EN": {Code: "EN", Name: "Enugu", Capital: "Enugu", Latitude: 6.4584, Longitude: 7.5464, Zone: "SOUTH EAST"},
"FC": {Code: "FC", Name: "Federal Capital Territory", Capital: "Abuja", Latitude: 9.0579, Longitude: 7.4951, Zone: "NORTH CENTRAL"},
"GO": {Code: "GO", Name: "Gombe", Capital: "Gombe", Latitude: 10.2897, Longitude: 11.1711, Zone: "NORTH EAST"},
"IM": {Code: "IM", Name: "Imo", Capital: "Owerri", Latitude: 5.4858, Longitude: 7.0355, Zone: "SOUTH EAST"},
"JI": {Code: "JI", Name: "Jigawa", Capital: "Dutse", Latitude: 11.7594, Longitude: 9.3389, Zone: "NORTH WEST"},
"KD": {Code: "KD", Name: "Kaduna", Capital: "Kaduna", Latitude: 10.5105, Longitude: 7.4165, Zone: "NORTH WEST"},
"KN": {Code: "KN", Name: "Kano", Capital: "Kano", Latitude: 12.0022, Longitude: 8.5920, Zone: "NORTH WEST"},
"KT": {Code: "KT", Name: "Katsina", Capital: "Katsina", Latitude: 12.9855, Longitude: 7.6171, Zone: "NORTH WEST"},
"KE": {Code: "KE", Name: "Kebbi", Capital: "Birnin Kebbi", Latitude: 12.4504, Longitude: 4.1999, Zone: "NORTH WEST"},
"KO": {Code: "KO", Name: "Kogi", Capital: "Lokoja", Latitude: 7.8023, Longitude: 6.7333, Zone: "NORTH CENTRAL"},
"KW": {Code: "KW", Name: "Kwara", Capital: "Ilorin", Latitude: 8.4966, Longitude: 4.5421, Zone: "NORTH CENTRAL"},
"LA": {Code: "LA", Name: "Lagos", Capital: "Ikeja", Latitude: 6.6018, Longitude: 3.3515, Zone: "SOUTH WEST"},
"NA": {Code: "NA", Name: "Nasarawa", Capital: "Lafia", Latitude: 8.4932, Longitude: 8.5153, Zone: "NORTH CENTRAL"},
"NI": {Code: "NI", Name: "Niger", Capital: "Minna", Latitude: 9.6139, Longitude: 6.5569, Zone: "NORTH CENTRAL"},
"OG": {Code: "OG", Name: "Ogun", Capital: "Abeokuta", Latitude: 7.1475, Longitude: 3.3619, Zone: "SOUTH WEST"},
"ON": {Code: "ON", Name: "Ondo", Capital: "Akure", Latitude: 7.2571, Longitude: 5.2058, Zone: "SOUTH WEST"},
"OS": {Code: "OS", Name: "Osun", Capital: "Osogbo", Latitude: 7.7827, Longitude: 4.5418, Zone: "SOUTH WEST"},
"OY": {Code: "OY", Name: "Oyo", Capital: "Ibadan", Latitude: 7.3775, Longitude: 3.9470, Zone: "SOUTH WEST"},
"PL": {Code: "PL", Name: "Plateau", Capital: "Jos", Latitude: 9.9271, Longitude: 8.8921, Zone: "NORTH CENTRAL"},
"RI": {Code: "RI", Name: "Rivers", Capital: "Port Harcourt", Latitude: 4.8156, Longitude: 7.0498, Zone: "SOUTH SOUTH"},
"SO": {Code: "SO", Name: "Sokoto", Capital: "Sokoto", Latitude: 13.0609, Longitude: 5.2476, Zone: "NORTH WEST"},
"TA": {Code: "TA", Name: "Taraba", Capital: "Jalingo", Latitude: 8.8937, Longitude: 11.3600, Zone: "NORTH EAST"},
"YO": {Code: "YO", Name: "Yobe", Capital: "Damaturu", Latitude: 11.7470, Longitude: 11.9608, Zone: "NORTH EAST"},
"ZA": {Code: "ZA", Name: "Zamfara", Capital: "Gusau", Latitude: 12.1702, Longitude: 6.6592, Zone: "NORTH WEST"},
}
NigerianStates contains geographic centroids and administrative capitals for all 36 States and FCT.
Functions ¶
func BaselineExtract ¶ added in v0.1.4
BaselineExtract provides an offline heuristic extractor for Nigerian addresses. It searches raw unstructured text for state names/codes and postcode patterns.
func BatchParseSeq ¶
BatchParseSeq yields an iter.Seq2 iterator with slice index and Result wrapper.
func ClearDiskCache ¶ added in v0.1.9
func ClearDiskCache() error
ClearDiskCache removes all custom in-memory buildings and deletes the persistent cache file.
func Coordinates ¶ added in v0.1.1
Coordinates parses any valid 11-character Nigerian postcode string and returns its latitude and longitude coordinates.
func DefaultCachePath ¶ added in v0.1.9
func DefaultCachePath() string
DefaultCachePath returns the standard user-level cache file path: ~/.postcode/cache.json
func ExportBuildingsJSON ¶ added in v0.1.9
ExportBuildingsJSON writes all cached custom building records to a JSON writer.
func GetCachePath ¶ added in v0.1.9
func GetCachePath() string
GetCachePath returns the active cache file path.
func GetCacheStats ¶ added in v0.1.9
GetCacheStats returns the number of custom cached building records and the file location.
func GoogleMapsURL ¶ added in v0.1.1
GoogleMapsURL parses any valid 11-character Nigerian postcode string and directly generates its Google Maps location URL.
func IsValid ¶ added in v0.1.9
IsValid reports whether raw is a valid Nigerian postcode with a recognized state code.
func LoadBuildingsCSV ¶ added in v0.1.9
LoadBuildingsCSV reads building records from a CSV reader. Expected header format: postcode,latitude,longitude,address,state_code,state_name,lga_code,lga_name,zone
func LoadBuildingsJSON ¶ added in v0.1.9
LoadBuildingsJSON reads building records from a JSON array or object reader and stores them in cache.
func LoadDiskCache ¶ added in v0.1.9
func LoadDiskCache() error
LoadDiskCache ensures disk cache entries from ~/.postcode/cache.json (or custom path) are loaded into the offline building registry.
func RegisterKnownBuilding ¶ added in v0.1.1
func RegisterKnownBuilding(rec BuildingRecord)
RegisterKnownBuilding allows applications to register custom building units into the offline geocoding cache.
func SaveDiskCache ¶ added in v0.1.9
func SaveDiskCache() error
SaveDiskCache persists all registered custom building records to the cache file.
func SetCachePath ¶ added in v0.1.9
SetCachePath overrides the default cache file path and loads existing entries.
Types ¶
type APIError ¶
type APIError struct {
StatusCode int `json:"-"`
Code string `json:"code"`
Message string `json:"message"`
RateLimit *RateLimitInfo `json:"-"`
RetryAfter time.Duration `json:"-"`
}
APIError represents an error returned by the NIPOST Postcode API gateway.
func (*APIError) IsInsufficientCredits ¶
func (*APIError) IsNotFound ¶
func (*APIError) IsRateLimit ¶
func (*APIError) IsUnauthorized ¶
func (*APIError) UnmarshalJSON ¶
UnmarshalJSON handles both the official nested envelope {"error": {"code": ..., "message": ...}} and flat payloads {"code": ..., "message": ...}.
type AdministrativeAddress ¶
type AdministrativeAddress struct {
State string `json:"state,omitempty"`
StateName string `json:"state_name,omitempty"`
LGA string `json:"lga,omitempty"`
LGAName string `json:"lga_name,omitempty"`
District string `json:"district,omitempty"`
DistrictName string `json:"district_name,omitempty"`
Area string `json:"area,omitempty"`
AreaName string `json:"area_name,omitempty"`
Unit string `json:"unit,omitempty"`
Zone string `json:"zone,omitempty"`
LocalityName string `json:"locality_name,omitempty"`
}
AdministrativeAddress details administrative boundaries up to area level (L2+).
type AgentDispatcher ¶ added in v0.1.4
type AgentDispatcher struct {
// contains filtered or unexported fields
}
AgentDispatcher handles incoming tool executions from AI agent frameworks.
func NewAgentDispatcher ¶ added in v0.1.4
func NewAgentDispatcher(client *Client) *AgentDispatcher
NewAgentDispatcher creates a dispatcher. If client is nil, the dispatcher operates in offline mode, servicing local validation, diagnostics, state listing, and reference geocoding.
func (*AgentDispatcher) Dispatch ¶ added in v0.1.4
Dispatch executes the specified tool by name with unparsed JSON arguments.
func (*AgentDispatcher) DispatchString ¶ added in v0.1.4
func (d *AgentDispatcher) DispatchString(ctx context.Context, name string, argsJSON []byte) (string, error)
DispatchString executes the tool and returns the result serialized as a JSON string, safe for direct injection into LLM response messages.
func (*AgentDispatcher) Tools ¶ added in v0.1.4
func (d *AgentDispatcher) Tools() []ToolDef
Tools returns the list of available tools.
type AgentGuardConfig ¶ added in v0.1.4
type AgentGuardConfig struct {
// MaxCommercialCallsPerRun limits the number of paid/commercial calls (Level 2/3) in a session.
// 0 means unlimited.
MaxCommercialCallsPerRun int
// MaxTotalCallsPerRun limits the total number of all gateway calls in a session.
// 0 means unlimited.
MaxTotalCallsPerRun int
// AutoDowngradeToLevel1 automatically downgrades Level 2/3 commercial requests to
// free Level 1 validity checks if commercial limits are reached or insufficient credits occur.
AutoDowngradeToLevel1 bool
// AutoFallbackToOffline automatically falls back to offline reference geocoding
// if gateway calls fail with 429 (rate limit) or 402 (insufficient credits).
AutoFallbackToOffline bool
}
AgentGuardConfig configures autonomous guardrails for AI agents to prevent runaway costs and infinite loops during tool-calling execution.
type AgentGuardMetrics ¶ added in v0.1.4
type AgentGuardMetrics struct {
TotalCalls int64 `json:"total_calls"`
CommercialCalls int64 `json:"commercial_calls"`
DowngradedCalls int64 `json:"downgraded_calls"`
OfflineFallbacks int64 `json:"offline_fallbacks"`
}
AgentGuardMetrics reports live telemetry for calls executed under agent guardrails.
type AssembledPostcode ¶
type AssembledPostcode struct {
Postcode string `json:"postcode"` // Canonical: "EK-01-A03-FK-01"
Display string `json:"display"` // Spaced: "EK 01 A03 FK 01"
Compact string `json:"compact"` // Compact: "EK01A03FK01"
}
AssembledPostcode represents the output of POST /v1/assembly/assemble.
func AssembleSegments ¶ added in v0.1.9
func AssembleSegments(segs Segments) (AssembledPostcode, error)
AssembleSegments validates and combines segments into an AssembledPostcode locally without network calls.
type AutocompleteResponse ¶
type AutocompleteResponse struct {
Segment string `json:"segment"`
Suggestions []AutocompleteSuggestion `json:"suggestions"`
}
AutocompleteResponse contains suggestions for the currently active segment.
type AutocompleteSuggestion ¶
AutocompleteSuggestion represents an individual suggestion returned by autocomplete.
type BuildingRecord ¶ added in v0.1.1
type BuildingRecord struct {
Postcode string // Canonical (e.g. "EK-01-A03-FK-01") or Compact ("EK01A03FK01")
Latitude float64
Longitude float64
Address string
StateCode string
StateName string
LGACode string
LGAName string
Zone string
}
BuildingRecord holds high-precision point geometry for a specific building unit.
func AllBuildingRecords ¶ added in v0.1.9
func AllBuildingRecords() []BuildingRecord
AllBuildingRecords returns all known building benchmark records and loaded custom cached buildings.
type Cache ¶ added in v0.1.4
type Cache interface {
Get(key string) (any, bool)
Set(key string, val any, ttl time.Duration)
Delete(key string)
Clear()
Len() int
}
Cache defines the interface for caching postcode gateway lookups and resolutions. Enables idempotency and prevents redundant paid API calls during AI agent loops.
type ChainGeocoder ¶ added in v0.1.9
type ChainGeocoder struct {
Geocoders []Geocoder
}
ChainGeocoder attempts each provided Geocoder in sequence until one succeeds.
func NewChainGeocoder ¶ added in v0.1.9
func NewChainGeocoder(geocoders ...Geocoder) *ChainGeocoder
NewChainGeocoder creates a composite geocoder.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClient ¶
func NewClient(opts ...ClientOption) (*Client, error)
NewClient instantiates a production-tuned HTTP client.
func (*Client) AgentMetrics ¶ added in v0.1.4
func (c *Client) AgentMetrics() AgentGuardMetrics
AgentMetrics returns live telemetry metrics for calls executed under agent guardrails.
func (*Client) Assemble ¶
Assemble builds canonical, display, and compact postcodes from individual segments. Numeric segments are zero-filled (e.g. "1" -> "01") and alpha segments are converted to uppercase.
func (*Client) Autocomplete ¶
Autocomplete retrieves segment-aware suggestions for a partial postcode input (e.g. "EK 01 A").
func (*Client) Disassemble ¶
Disassemble decomposes a postcode string into its 5 structural segments.
func (*Client) Health ¶ added in v0.1.9
Health checks the operational status of the gateway via GET /healthz. Returns nil if the gateway responds with HTTP 200 OK.
func (*Client) Lookup ¶
func (c *Client) Lookup(ctx context.Context, code string, level LookupLevel) (*LookupResponse, error)
Lookup queries the gateway for detailed attributes of a postcode. Level defaults to Level1 (free) if 0 or unspecified.
func (*Client) Nearby ¶
func (c *Client) Nearby(ctx context.Context, params NearbyParams) (*NearbyResponse, error)
Nearby searches for active postcode units within a radius (default 300m) of a coordinate or reference postcode.
func (*Client) NearbyPostcode ¶ added in v0.1.9
func (c *Client) NearbyPostcode(ctx context.Context, code string, radiusM float64) (*NearbyResponse, error)
NearbyPostcode searches for active units within a radius of a reference postcode.
func (*Client) RateLimit ¶
func (c *Client) RateLimit() *RateLimitInfo
RateLimit returns the most recent rate limit quotas reported by the NIPOST gateway, or nil if no request has yet returned rate limit headers.
func (*Client) ReferenceAreas ¶ added in v0.1.9
func (c *Client) ReferenceAreas(ctx context.Context, state, lga, district string) ([]NamedCode, error)
ReferenceAreas queries all postal area codes under a state, LGA, and district (GET /v1/reference/areas?state=...&lga=...&district=...). Areas have no human name (code only). Free, no credits consumed.
func (*Client) ReferenceDistricts ¶ added in v0.1.9
ReferenceDistricts queries all postal district codes under a state and LGA (GET /v1/reference/districts?state=...&lga=...). Districts have no human name (code only). Free, no credits consumed.
func (*Client) ReferenceLGAs ¶ added in v0.1.9
ReferenceLGAs queries all Local Government Areas for a given state code (GET /v1/reference/lgas?state=...). This endpoint is free and consumes no credits.
func (*Client) ReferenceStates ¶ added in v0.1.9
ReferenceStates queries the official precomputed catalog for all 37 Nigerian states (GET /v1/reference/states). This endpoint is free and consumes no credits.
func (*Client) ResolveLocation ¶ added in v0.1.1
ResolveLocation resolves rich geographic metadata for a postcode. It enriches the location via the NIPOST gateway at the highest available commercial tier (Level 3 down to Level 1) if configured, adopting any explicit point geometry returned by the gateway (e.g. enterprise accounts or simulator). If point geometry is not present, it leverages the SDK's high-precision offline reference geocoding engine (building benchmarks -> LGA centroid -> State centroid) to guarantee reliable coordinates and mapping URLs.
func (*Client) Reverse ¶
func (c *Client) Reverse(ctx context.Context, params ReverseParams) (*ReverseResponse, error)
Reverse resolves a geographic coordinate to the nearest active postcode unit.
func (*Client) ReverseCoordinates ¶ added in v0.1.9
func (c *Client) ReverseCoordinates(ctx context.Context, lat, lng, maxDistanceM float64) (*ReverseResponse, error)
ReverseCoordinates resolves geographic coordinates directly to the nearest active postcode unit.
type ClientOption ¶
type ClientOption func(*Client)
func WithAPIKey ¶
func WithAPIKey(key string) ClientOption
WithAPIKey sets the NIPOST API key sent in the X-API-Key header. An apiKey is optional for public endpoints (L1 lookup, search, assembly).
func WithAgentGuard ¶ added in v0.1.4
func WithAgentGuard(cfg AgentGuardConfig) ClientOption
WithAgentGuard configures budget and safety ceilings for autonomous agents.
func WithBaseTransport ¶
func WithBaseTransport(rt http.RoundTripper) ClientOption
WithBaseTransport sets the underlying round tripper underneath the retry middleware.
func WithBaseURL ¶
func WithBaseURL(customURL string) ClientOption
WithBaseURL overrides the default gateway URL (e.g. for testing with httptest.Server).
func WithCache ¶ added in v0.1.4
func WithCache(cache Cache) ClientOption
WithCache configures a custom cache implementation for the client.
func WithDefaultCache ¶ added in v0.1.4
func WithDefaultCache() ClientOption
WithDefaultCache configures a standard in-memory TTL cache (1000 items, 30m TTL).
func WithGeocoder ¶ added in v0.1.9
func WithGeocoder(g Geocoder) ClientOption
WithGeocoder configures an external geocoder for resolving textual address locations into coordinates.
func WithGoogleMapsKey ¶ added in v0.1.9
func WithGoogleMapsKey(key string) ClientOption
WithGoogleMapsKey configures Google Maps Geocoding API key for the client's geocoding chain.
func WithRateLimitRetry ¶
func WithRateLimitRetry(enabled bool, maxDelay time.Duration) ClientOption
WithRateLimitRetry configures automatic retry on 429 Too Many Requests responses. If enabled is false, 429 responses will not be retried. maxDelay sets the maximum duration the client is willing to sleep for a rate limit cooldown.
func WithRetryConfig ¶
func WithRetryConfig(cfg RetryConfig) ClientOption
WithRetryConfig configures backoff, jitter, and retry limits.
func WithTelemetry ¶
func WithTelemetry(t Telemetry) ClientOption
WithTelemetry registers custom observability hooks.
func WithTimeout ¶
func WithTimeout(d time.Duration) ClientOption
WithTimeout sets the overall client request timeout.
func WithTransport ¶
func WithTransport(rt http.RoundTripper) ClientOption
WithTransport explicitly overrides the entire round tripper stack (bypassing retries).
type DiagnosticReport ¶ added in v0.1.4
type DiagnosticReport struct {
Input string `json:"input"`
Valid bool `json:"valid"`
Normalized string `json:"normalized,omitempty"` // Hyphenated canonical form if valid or recoverable
CleanLength int `json:"clean_length"` // Number of alphanumeric characters found
Diagnoses []SegmentDiagnosis `json:"diagnoses,omitempty"`
ActionableTip string `json:"actionable_tip,omitempty"` // Summary recommendation for the caller/agent
FormatScore float64 `json:"format_score"` // Structural conformance score (0.0 to 100.0)
}
DiagnosticReport provides deep structural and administrative analysis of a postcode string. Designed for humans and autonomous AI agents to self-correct invalid inputs.
func Diagnose ¶ added in v0.1.4
func Diagnose(raw string) DiagnosticReport
Diagnose inspects a candidate postcode string, performing exhaustive grammar, structural, and administrative checks. Returns an actionable DiagnosticReport that AI agents can use to understand the error and formulate corrections.
type EvalResult ¶ added in v0.1.4
type EvalResult struct {
TotalSamples int `json:"total_samples"`
StateAccuracy float64 `json:"state_accuracy"`
PostcodeAccuracy float64 `json:"postcode_accuracy"`
ValidRate float64 `json:"valid_rate"`
AvgFormatScore float64 `json:"avg_format_score"`
DurationMs int64 `json:"duration_ms"`
}
EvalResult contains accuracy and performance scores from evaluating an agent on synthetic data.
func EvaluateAgent ¶ added in v0.1.4
func EvaluateAgent(dataset []SyntheticAddress, extractor func(raw string) (string, string)) EvalResult
EvaluateAgent runs an extraction function against a synthetic dataset and tallies accuracy metrics.
type GeneratorOptions ¶ added in v0.1.4
type GeneratorOptions struct {
Count int `json:"count"`
Seed uint64 `json:"seed,omitempty"`
NoiseRate float64 `json:"noise_rate,omitempty"` // 0.0 to 1.0 (default 0.3)
}
GeneratorOptions configures the synthetic Nigerian address generator.
type Geocoder ¶ added in v0.1.9
type Geocoder interface {
Geocode(ctx context.Context, query string) (lat, lng float64, err error)
}
Geocoder resolves a geographic textual address or landmark query to latitude and longitude coordinates.
type GoogleMapsGeocoder ¶ added in v0.1.9
type GoogleMapsGeocoder struct {
APIKey string
BaseURL string // Defaults to "https://geocode.googleapis.com"
HTTPClient *http.Client
}
GoogleMapsGeocoder resolves coordinates using the modern Google Maps Geocoding API v4 (https://geocode.googleapis.com/v4/geocode/address), with automatic fallback to v3.
func NewGoogleMapsGeocoder ¶ added in v0.1.9
func NewGoogleMapsGeocoder(apiKey string, client *http.Client) *GoogleMapsGeocoder
NewGoogleMapsGeocoder creates a Geocoder backed by Google Maps Geocoding API v4.
type LGARecord ¶ added in v0.1.1
type LGARecord struct {
StateCode string
LGACode string
Name string
Latitude float64
Longitude float64
}
LGARecord holds reference coordinates and names for an LGA within a state.
type Location ¶ added in v0.1.1
type Location struct {
Postcode string `json:"postcode"` // Canonical hyphenated: "EK-01-A03-FK-01"
Compact string `json:"compact"` // Compact 11-char: "EK01A03FK01"
Latitude float64 `json:"latitude"` // Geographic latitude (-90 to +90)
Longitude float64 `json:"longitude"` // Geographic longitude (-180 to +180)
Address string `json:"address,omitempty"` // Known street/building address if available
StateCode string `json:"state_code"` // 2-letter state code (e.g. "EK")
StateName string `json:"state_name"` // Full state name (e.g. "Ekiti")
LGACode string `json:"lga_code,omitempty"` // 2-digit LGA code (e.g. "01")
LGAName string `json:"lga_name,omitempty"` // Full LGA name (e.g. "Ado Ekiti")
Zone string `json:"zone,omitempty"` // Geopolitical zone (e.g. "SOUTH WEST")
Precision Precision `json:"precision"` // Coordinate precision tier (placed at end to minimize struct alignment padding)
}
Location encapsulates geographic coordinates, address descriptors, and mapping URLs.
func ResolveLocation ¶ added in v0.1.1
ResolveLocation parses any valid 11-character Nigerian postcode string (compact, hyphenated, or spaced) and returns its resolved geographic Location. Uses local administrative reference data without requiring network calls.
func (Location) AppleMapsURL ¶ added in v0.1.1
AppleMapsURL returns an Apple Maps URL for iOS/macOS devices. Format: https://maps.apple.com/?ll=lat,lng&q=...
func (Location) Coordinates ¶ added in v0.1.1
Coordinates returns the latitude and longitude as a float64 pair.
func (Location) GoogleMapsDirectionsURL ¶ added in v0.1.1
GoogleMapsDirectionsURL returns a Google Maps navigation/directions URL to this location. Format: https://www.google.com/maps/dir/?api=1&destination=lat,lng
func (Location) GoogleMapsURL ¶ added in v0.1.1
GoogleMapsURL returns a standard, universal Google Maps search URL with exact coordinates when Precision is Building, or a rich search query for coarse (LGA/State) locations. Format: https://www.google.com/maps/search/?api=1&query=...
func (Location) IsZero ¶ added in v0.1.1
IsZero reports whether the location represents a zero/uninitialized value.
func (Location) OpenStreetMapURL ¶ added in v0.1.1
OpenStreetMapURL returns an OpenStreetMap pin URL.
func (Location) SearchQuery ¶ added in v0.1.1
SearchQuery produces a descriptive location query string suitable for search engines (e.g. "Ado Ekiti, Ekiti State, Nigeria" or "Abuja Municipal, Federal Capital Territory, Nigeria").
type LookupLevel ¶
type LookupLevel int
LookupLevel specifies the depth of attributes returned by a lookup request. Per official NIPOST documentation (docs.postcode.gov.ng/concepts/lookup-levels): Lookup responses are graded into 3 cumulative levels (L1–L3):
- Level 1 (Free, Public): Validity status (valid: true/false) and canonical postcode.
- Level 2 (Commercial): Administrative address (state, LGA, district, area) and street address.
- Level 3 (Commercial): Full building use status (residential, commercial, mixed, etc.) and all lower levels.
Standard commercial API keys are strictly capped at Level 3 (LevelMax). Attempting to request a level higher than your organization's granted quota yields a 403 Forbidden ("key lacks scope or level").
Note on Level 4 & Level 5: In raw backend OpenAPI schemas (docs.postcode.gov.ng/api-reference/graded-postcode-lookup-levels-1–5-cumulative), levels 4 and 5 represent unreleased or restricted government tiers:
- Level 4: other_building_info (unreleased building metadata)
- Level 5: point_geometry (restricted government GIS coordinates)
Standard commercial keys do NOT have access to L4/L5. The SDK defines Level4 and Level5 for backward compatibility and private enterprise mock environments.
const ( LevelDefault LookupLevel = 0 // Default to Level 1 Level1 LookupLevel = 1 // Free: Validity check and canonical postcode Level2 LookupLevel = 2 // Commercial: Administrative boundaries and street address Level3 LookupLevel = 3 // Commercial: Building use status and unit metadata (Official Maximum) LevelMax LookupLevel = 3 // Standard commercial maximum level (L3) // Restricted / Internal tiers (not accessible with standard API keys): Level4 LookupLevel = 4 // Internal/Enterprise: Additional building info Level5 LookupLevel = 5 // Restricted: High-precision point geometry (requires special government grant) )
type LookupResponse ¶
type LookupResponse struct {
Postcode string `json:"postcode"`
Valid bool `json:"valid"`
AdministrativeAddress *AdministrativeAddress `json:"administrative_address,omitempty"`
RecentHouseAddress *RecentHouseAddress `json:"recent_house_address,omitempty"`
BuildingUseStatus string `json:"building_use_status,omitempty"`
OtherBuildingInfo map[string]any `json:"other_building_info,omitempty"`
PointGeometry *PointGeometry `json:"point_geometry,omitempty"`
}
LookupResponse represents the graded attributes returned by GET /v1/lookup.
type MCPOption ¶ added in v0.1.4
type MCPOption func(*MCPServer)
MCPOption configures an MCPServer instance.
func WithMCPLogger ¶ added in v0.1.4
WithMCPLogger specifies a logger for internal MCP diagnostics (must write to stderr).
type MCPServer ¶ added in v0.1.4
type MCPServer struct {
// contains filtered or unexported fields
}
MCPServer implements a dual-era Model Context Protocol (MCP) server conforming to the MCP 2026-07-28 specification, with backward compatibility for legacy clients. Operates statelessly over stdio or any streaming io.ReadWriter.
func NewMCPServer ¶ added in v0.1.4
NewMCPServer creates a ready-to-run MCP server. If client is nil, the server operates in offline mode, servicing local validation, diagnostics, and reference geocoding.
type MemoryCache ¶ added in v0.1.4
type MemoryCache struct {
// contains filtered or unexported fields
}
MemoryCache provides a thread-safe, in-memory TTL cache with size bounding.
func NewMemoryCache ¶ added in v0.1.4
func NewMemoryCache(maxEntries int, defaultTTL time.Duration) *MemoryCache
NewMemoryCache creates a memory cache. If maxEntries <= 0, defaults to 1000 entries. If defaultTTL <= 0, defaults to 30 minutes.
func (*MemoryCache) Clear ¶ added in v0.1.4
func (c *MemoryCache) Clear()
Clear flushes all entries from the cache.
func (*MemoryCache) Delete ¶ added in v0.1.4
func (c *MemoryCache) Delete(key string)
Delete removes a specific key from the cache.
func (*MemoryCache) Get ¶ added in v0.1.4
func (c *MemoryCache) Get(key string) (any, bool)
Get retrieves an item from the cache if present and unexpired.
func (*MemoryCache) Len ¶ added in v0.1.4
func (c *MemoryCache) Len() int
Len returns the current count of items in the cache.
type MetricsRecorder ¶
type MetricsRecorder interface {
RecordDuration(ctx context.Context, method, endpoint string, statusCode int, duration time.Duration)
AddInflight(ctx context.Context, delta int64)
}
MetricsRecorder defines standard metrics contracts for client operations.
type NamedCode ¶ added in v0.1.9
NamedCode represents a geographic administrative unit code with an optional human name. For states and LGAs, Name is populated. For districts and areas, Name is omitted or empty.
type NearbyParams ¶
type NearbyParams struct {
Postcode string `json:"postcode,omitempty"` // Optional reference postcode (auto-resolves centroid if coordinates are 0)
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
RadiusM float64 `json:"radius_m"` // Search radius in meters (default 300, max 300)
}
NearbyParams configures location search around a geographic coordinate or reference postcode.
type NearbyResponse ¶
type NearbyResponse struct {
Results []NearbyUnit `json:"results"`
}
NearbyResponse contains location units within the requested radius.
func (*NearbyResponse) UnmarshalJSON ¶ added in v0.1.9
func (r *NearbyResponse) UnmarshalJSON(data []byte) error
UnmarshalJSON supports both a direct slice of units `[...]` (returned by live NIPOST Gateway) and an object payload `{"results": [...]}` (returned by simulators/proxies).
type NearbyUnit ¶
type NearbyUnit struct {
Postcode string `json:"postcode"`
Display string `json:"display"`
DistanceM float64 `json:"distance_m"`
Confidence string `json:"confidence"`
StateName string `json:"state_name,omitempty"`
LGAName string `json:"lga_name,omitempty"`
Address string `json:"address,omitempty"`
}
NearbyUnit represents a building unit found near a coordinate.
func SearchNearbyBuildingsOffline ¶ added in v0.1.9
func SearchNearbyBuildingsOffline(lat, lng, radiusM float64) []NearbyUnit
SearchNearbyBuildingsOffline searches local embedded and cached buildings within radiusM meters of (lat, lng).
type NominatimGeocoder ¶ added in v0.1.9
type NominatimGeocoder struct {
UserAgent string
BaseURL string // Defaults to "https://nominatim.openstreetmap.org"
HTTPClient *http.Client
}
NominatimGeocoder resolves coordinates using OpenStreetMap Nominatim with country restricted to Nigeria.
func NewNominatimGeocoder ¶ added in v0.1.9
func NewNominatimGeocoder(userAgent string, client *http.Client) *NominatimGeocoder
NewNominatimGeocoder creates a Geocoder backed by OpenStreetMap Nominatim.
type PointGeometry ¶
type PointGeometry struct {
Type string `json:"type,omitempty"`
Coordinates []float64 `json:"coordinates,omitempty"` // [lng, lat]
}
PointGeometry represents GeoJSON point coordinates (L5).
type Postcode ¶
type Postcode struct {
// contains filtered or unexported fields
}
Postcode represents an immutable, validated 11-byte Nigerian postcode. Backed by a fixed byte array to ensure zero heap escapes.
func (Postcode) AppendText ¶
AppendText implements encoding.TextAppender for zero-alloc formatting. Outputs the spaced format: "AA 99 H77 BB 55".
func (Postcode) BuildingUnit ¶
func (Postcode) Compact ¶ added in v0.1.4
Compact returns the compact 11-character representation without delimiters (e.g. "EK01A03FK01"). Alias for Raw().
func (Postcode) Coordinates ¶ added in v0.1.1
Coordinates returns the latitude and longitude coordinates for this postcode.
func (Postcode) Formatted ¶
Formatted returns the canonical hyphenated representation (e.g. "EK-01-A03-FK-01").
func (Postcode) GoogleMapsURL ¶ added in v0.1.1
GoogleMapsURL returns a direct Google Maps search URL with exact coordinates.
func (Postcode) Location ¶ added in v0.1.1
Location returns the resolved geographic location and mapping URLs for this postcode. Resolves offline via built-in administrative and building registries without network calls.
func (Postcode) MarshalText ¶
func (*Postcode) UnmarshalText ¶
type Precision ¶ added in v0.1.1
type Precision uint8
Precision indicates the resolution accuracy of the resolved coordinates.
const ( // PrecisionBuilding indicates exact building-level point geometry. PrecisionBuilding Precision = iota // PrecisionArea indicates area or street axis level resolution. PrecisionArea // PrecisionDistrict indicates district-level centroid resolution. PrecisionDistrict // PrecisionLGA indicates Local Government Area centroid resolution. PrecisionLGA // PrecisionState indicates State-level centroid resolution. PrecisionState )
func (Precision) MarshalJSON ¶ added in v0.1.1
MarshalJSON implements json.Marshaler.
func (Precision) MarshalText ¶ added in v0.1.1
MarshalText implements encoding.TextMarshaler.
func (Precision) String ¶ added in v0.1.1
String returns the human-readable description of the precision level.
func (*Precision) UnmarshalJSON ¶ added in v0.1.1
UnmarshalJSON implements json.Unmarshaler to accept both string ("building") and numeric (0) forms.
func (*Precision) UnmarshalText ¶ added in v0.1.1
UnmarshalText implements encoding.TextUnmarshaler.
type RateLimitInfo ¶
type RateLimitInfo struct {
Limit int // Maximum requests allowed in current window (from X-RateLimit-Limit)
Remaining int // Remaining requests in current window (from X-RateLimit-Remaining)
ResetAt time.Time // Timestamp when quota resets (from X-RateLimit-Reset or Retry-After)
RetryAfter time.Duration // Cooldown duration requested by server (from Retry-After or X-RateLimit-Reset)
}
RateLimitInfo contains the rate-limiting quotas returned by the NIPOST API gateway as documented in https://docs.postcode.gov.ng/authentication.
func ParseRateLimitInfo ¶
func ParseRateLimitInfo(h http.Header) *RateLimitInfo
ParseRateLimitInfo extracts rate limit quotas and cooldown durations from HTTP response headers.
type RecentHouseAddress ¶
type RecentHouseAddress struct {
Address string `json:"address,omitempty"`
Recent string `json:"recent,omitempty"`
HouseNumber string `json:"house_number,omitempty"`
StreetName string `json:"street_name,omitempty"`
LocalityName string `json:"locality_name,omitempty"`
}
RecentHouseAddress contains residential and street metadata (L2+).
type RetryConfig ¶
type RetryConfig struct {
MaxRetries int // Maximum retry attempts for transient errors (default: 3)
BaseDelay time.Duration // Initial exponential backoff delay (default: 100ms)
MaxDelay time.Duration // Maximum exponential backoff delay (default: 2s)
DisableRateLimit bool // If true, 429 Too Many Requests will not be retried automatically
MaxRateLimitDelay time.Duration // Maximum sleep duration client will wait for a 429 cooldown (default: 10s)
}
RetryConfig configures backoff, jitter, and rate-limit handling for HTTP requests.
type RetryTransport ¶
type RetryTransport struct {
Base http.RoundTripper
Config RetryConfig
}
func NewRetryTransport ¶
func NewRetryTransport(base http.RoundTripper, cfg RetryConfig) *RetryTransport
type ReverseParams ¶
type ReverseParams struct {
Latitude float64
Longitude float64
MaxDistanceM float64 // Search radius in meters (default 25, max 250)
}
ReverseParams configures reverse geocoding to snap coordinates to the nearest unit.
type ReverseResponse ¶
type ReverseResponse struct {
Found bool `json:"found"`
Coordinate []float64 `json:"coordinate"` // [lng, lat]
Unit *NearbyUnit `json:"unit,omitempty"`
Area string `json:"area,omitempty"`
District string `json:"district,omitempty"`
State string `json:"state,omitempty"`
Message string `json:"message,omitempty"`
RadiusM float64 `json:"radius_m"`
}
ReverseResponse represents the result of reverse geocoding a coordinate.
func ReverseCoordinatesOffline ¶ added in v0.1.9
func ReverseCoordinatesOffline(lat, lng, maxDistanceM float64) *ReverseResponse
ReverseCoordinatesOffline resolves geographic coordinates to the closest building unit in the local database.
type SegmentDiagnosis ¶ added in v0.1.4
type SegmentDiagnosis struct {
Segment string `json:"segment"` // "Length", "State", "LGA", "District", "Area", "BuildingUnit"
Input string `json:"input"` // The actual segment characters received
Expected string `json:"expected"` // What the NIPOST grammar requires
Message string `json:"message"` // Human & agent readable explanation
Suggestions []string `json:"suggestions,omitempty"` // Actionable candidates for agent self-correction
}
SegmentDiagnosis describes an issue identified in a specific segment of a postcode.
type Segments ¶
type Segments struct {
State string `json:"state"`
LGA string `json:"lga"`
District string `json:"district"`
Area string `json:"area"`
Unit string `json:"unit"`
}
Segments represents the 5 administrative components of a Nigerian postcode.
func NormalizeSegments ¶ added in v0.1.9
NormalizeSegments trims whitespace, converts alpha segments to uppercase, and zero-fills single-digit numeric segments (e.g. "1" -> "01") according to official NIPOST rules.
type Span ¶
type Span interface {
End()
RecordError(err error)
SetAttribute(key, value string)
SetStatus(code int, msg string)
}
Span encapsulates active span operations without coupling to any trace vendor.
type StateRecord ¶ added in v0.1.1
type StateRecord struct {
Code string
Name string
Capital string
Latitude float64
Longitude float64
Zone string
}
StateRecord holds reference coordinates and metadata for a Nigerian state.
type SyntheticAddress ¶ added in v0.1.4
type SyntheticAddress struct {
RawText string `json:"raw_text"`
ExpectedState string `json:"expected_state"`
ExpectedStateCode string `json:"expected_state_code"`
ExpectedLGA string `json:"expected_lga,omitempty"`
ExpectedPostcode string `json:"expected_postcode,omitempty"`
ExpectedLat float64 `json:"expected_lat,omitempty"`
ExpectedLng float64 `json:"expected_lng,omitempty"`
NoiseType string `json:"noise_type,omitempty"`
}
SyntheticAddress represents a synthesized Nigerian address with ground-truth labels. Used to benchmark and evaluate AI agent entity extraction, validation, and geocoding accuracy.
func GenerateSyntheticDataset ¶ added in v0.1.4
func GenerateSyntheticDataset(opts GeneratorOptions) []SyntheticAddress
GenerateSyntheticDataset produces a slice of realistic synthetic Nigerian addresses.
type Telemetry ¶
type Telemetry struct {
Tracer Tracer
Metrics MetricsRecorder
}
Telemetry bundles tracing and metrics hooks.
func NopTelemetry ¶
func NopTelemetry() Telemetry
NopTelemetry provides zero-overhead, no-op telemetry by default.
type ToolDef ¶ added in v0.1.4
type ToolDef struct {
Name string `json:"name"`
Description string `json:"description"`
Parameters map[string]any `json:"parameters"`
}
ToolDef describes an agent-executable function schema compliant with JSON Schema Draft-07.
func DefaultAgentTools ¶ added in v0.1.4
func DefaultAgentTools() []ToolDef
DefaultAgentTools returns the standard suite of tool declarations for Nigerian postcode operations.
func (ToolDef) AnthropicTool ¶ added in v0.1.4
AnthropicTool formats the tool declaration for the Anthropic Claude Messages API.
func (ToolDef) GeminiFunctionDeclaration ¶ added in v0.1.4
GeminiFunctionDeclaration formats the tool declaration for Google Gemini / Google GenAI SDK.
func (ToolDef) OpenAITool ¶ added in v0.1.4
OpenAITool formats the tool declaration for OpenAI, Mistral, Groq, and Ollama APIs.
type ValidationError ¶ added in v0.1.4
type ValidationError struct {
Report DiagnosticReport
}
ValidationError represents a validation failure enriched with an actionable DiagnosticReport.
func (*ValidationError) Error ¶ added in v0.1.4
func (e *ValidationError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
postcode
module
|
|
|
examples
|
|
|
ai_agent_guardrails
command
|
|
|
ai_synthetic_eval
command
|
|
|
otelpostcode
module
|
|