UK neighbourhood research from government open data: postcode reports, comparisons, 45 datasets.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Compare two to five UK postcodes on chosen categories, aligned measure by measure. Fetches each postcode's report concurrently and lines the facts up in a table, so you can answer "which of these is better connected / quieter / cheaper" in one call instead of several. Args: - postcodes (string[]): 2-5 UK postcodes - categories (string[]): 1-6 of demographics, crime, deprivation, prices, broadband, mobile, noise, transport, amenities, schools, environment - response_format ('markdown' | 'json'): default 'markdown' Returns: One row per measure with a column per postcode, each cell carrying the value, its band, and the category status for that postcode. Caveats collect anything that makes a row not strictly comparable. Comparability warnings you must respect, and which this tool surfaces: - Deprivation ranks from different UK nations are NOT comparable — different indices over different numbers of areas. - A measure missing for one postcode because the dataset does not cover that nation is not a low score; the cell says "out_of_coverage". - Ofcom mobile figures describe a whole local authority, so two postcodes in the same authority will always be identical. - Crime counts describe a 1 km square and depend on each police force submitting data; a very low count can be a gap rather than a quiet street. Examples: - "Which has better broadband, SW11 1AA or M1 1AE?" -> postcodes=[...], categories=["broadband"] - "Compare these three on crime and schools" -> categories=["crime","schools"] Don't use when: you have one postcode (use postcode_report) or want the underlying datasets (use postcode_search_datasets).
Two to five UK postcodes to compare, e.g. ["SW11 1AA", "M1 1AE"]
Which categories to compare on. Keep it tight — comparing all eleven across five postcodes produces a very large answer.
'markdown' for a side-by-side table, 'json' for the structured comparison
Compare two to five UK postcodes on chosen categories, aligned measure by measure. Fetches each postcode's report concurrently and lines the facts up in a table, so you can answer "which of these is better connected / quieter / cheaper" in one call instead of several. Args: - postcodes (string[]): 2-5 UK postcodes - categories (string[]): 1-6 of demographics, crime, deprivation, prices, broadband, mobile, noise, transport, amenities, schools, environment - response_format ('markdown' | 'json'): default 'markdown' Returns: One row per measure with a column per postcode, each cell carrying the value, its band, and the category status for that postcode. Caveats collect anything that makes a row not strictly comparable. Comparability warnings you must respect, and which this tool surfaces: - Deprivation ranks from different UK nations are NOT comparable — different indices over different numbers of areas. - A measure missing for one postcode because the dataset does not cover that nation is not a low score; the cell says "out_of_coverage". - Ofcom mobile figures describe a whole local authority, so two postcodes in the same authority will always be identical. - Crime counts describe a 1 km square and depend on each police force submitting data; a very low count can be a gap rather than a quiet street. Examples: - "Which has better broadband, SW11 1AA or M1 1AE?" -> postcodes=[...], categories=["broadband"] - "Compare these three on crime and schools" -> categories=["crime","schools"] Don't use when: you have one postcode (use postcode_report) or want the underlying datasets (use postcode_search_datasets).
| Argument | Type | Description |
|---|---|---|
| postcodes* | array | Two to five UK postcodes to compare, e.g. ["SW11 1AA", "M1 1AE"] |
| categories* | array | Which categories to compare on. Keep it tight — comparing all eleven across five postcodes produces a very large answer. |
| response_format | string | 'markdown' for a side-by-side table, 'json' for the structured comparison |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postcodes",
"categories"
],
"properties": {
"postcodes": {
"type": "array",
"items": {
"type": "string",
"maxLength": 10,
"minLength": 5
},
"maxItems": 5,
"minItems": 2,
"description": "Two to five UK postcodes to compare, e.g. [\"SW11 1AA\", \"M1 1AE\"]"
},
"categories": {
"type": "array",
"items": {
"enum": [
"demographics",
"crime",
"deprivation",
"prices",
"broadband",
"mobile",
"noise",
"transport",
"amenities",
"schools",
"environment"
],
"type": "string"
},
"maxItems": 6,
"minItems": 1,
"description": "Which categories to compare on. Keep it tight — comparing all eleven across five postcodes produces a very large answer."
},
"response_format": {
"enum": [
"markdown",
"json"
],
"type": "string",
"default": "markdown",
"description": "'markdown' for a side-by-side table, 'json' for the structured comparison"
}
}
}Full registry entry for one dataset, by id. Returns everything needed to call the source yourself: its home page, machine-readable endpoint, API documentation, format, licence, geographic coverage, update cadence, and the concrete questions it can answer. Args: - id (string): registry id, e.g. "police-street-crime", "land-registry-ppd", "ea-flood" - response_format ('markdown' | 'json'): default 'markdown' Examples: - "How do I call the police API?" -> id="police-street-crime" - "What licence is Price Paid under?" -> id="land-registry-ppd" Errors: - Returns the closest matching ids when the id is not found.
| Argument | Type | Description |
|---|---|---|
| id* | string | Registry id, e.g. "police-street-crime" — find one with postcode_search_datasets |
| response_format | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"maxLength": 60,
"minLength": 2,
"description": "Registry id, e.g. \"police-street-crime\" — find one with postcode_search_datasets"
},
"response_format": {
"enum": [
"markdown",
"json"
],
"type": "string",
"default": "markdown"
}
}
}Resolve a UK postcode to its geography — coordinates, local authority, ward, constituency, LSOA/MSOA/output area, police force, rural-urban class and deprivation rank. One fast call with no downstream data fetching. Use it to check a postcode exists, to get the codes needed for other datasets, or when you only need where somewhere is rather than what it is like. Args: - postcode (string): UK postcode, spaces optional - response_format ('markdown' | 'json'): default 'markdown' Returns: Coordinates, administrative geography, statistical geography codes (LSOA/MSOA/OA — these are the keys most UK open datasets are published against), and the deprivation rank with the index it came from. Examples: - "Where is SW11 1AA?" -> postcode="SW11 1AA" - "What LSOA covers M1 1AE?" -> postcode="M1 1AE" - "Is XY1 2AB a real postcode?" -> postcode="XY1 2AB" (returns an error with suggestions) Don't use when: you want data about the area — use postcode_report instead. Note: deprivation ranks are NOT comparable between UK nations. Each nation ranks its own areas against its own index, over a different number of areas; the index and its size are returned so you do not compare them by mistake.
| Argument | Type | Description |
|---|---|---|
| postcode* | string | A UK postcode, e.g. "SW11 1AA" |
| response_format | string | 'markdown' to read, 'json' for the structured record |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postcode"
],
"properties": {
"postcode": {
"type": "string",
"maxLength": 10,
"minLength": 5,
"description": "A UK postcode, e.g. \"SW11 1AA\""
},
"response_format": {
"enum": [
"markdown",
"json"
],
"type": "string",
"default": "markdown",
"description": "'markdown' to read, 'json' for the structured record"
}
}
}Full neighbourhood report for one UK postcode, assembled live from UK government open data. Covers eleven categories: demographics (Census 2021), crime (data.police.uk), deprivation (IMD/WIMD/SIMD/NIMDM), property prices (HM Land Registry), broadband and 5G (Ofcom), noise (Defra), transport, amenities (OpenStreetMap), schools (DfE register: name, phase and distance only, no Ofsted grades) and planning constraints (Planning Data platform, Environment Agency). Every figure carries the geography it describes (a postcode, an LSOA of ~1,500 people, or a whole local authority), the period it covers, and a benchmark where one exists. Read those: a crime count describes a 1 km square, and Ofcom mobile coverage describes an entire local authority, not the street. Args: - postcode (string): UK postcode, spaces optional - categories (string[], optional): subset to fetch; omit for all eleven - include_sources (boolean): append publisher and licence per category (default false) - response_format ('markdown' | 'json'): default 'markdown' Returns: Per category: a status, a one-paragraph summary, the facts (label, value, band, benchmark, geography, period, source id) and any caveats. Statuses that are normal rather than failures: - "out_of_coverage": the dataset genuinely does not cover this nation. Census tables are England & Wales; police.uk excludes Scotland; Planning Data, Defra noise and the DfE school register are England-only. The reason and the devolved equivalent are given. - "unavailable": a pre-built extract has not been generated for this area yet (noise, currently). - "partial": some sources answered and some did not; check notes. Examples: - "What's SW11 1AA like?" -> postcode="SW11 1AA" - "Is the broadband any good at M1 1AE?" -> postcode="M1 1AE", categories=["broadband","mobile"] - "Crime and schools near LA23 1AA" -> postcode="LA23 1AA", categories=["crime","schools"] Errors: - "No such postcode" with suggestions when the postcode does not exist - Terminated postcodes are reported with the year they were withdrawn Not a survey, valuation or conveyancing search. Check anything decision-critical against the source.
| Argument | Type | Description |
|---|---|---|
Search a curated registry of 45 UK open datasets and APIs for property and neighbourhood research. Each entry records the dataset's home page, its machine-readable endpoint, format, licence, geographic coverage, update cadence, and the concrete questions it can answer. Use it to find the right source for something this server does not report directly — EPC ratings, planning applications, flood risk, council tax bands, bus timetables, air quality, ground stability, land ownership. Args: - query (string, optional): free text over name, publisher, category, endpoint and questions - category (string, optional): category prefix, e.g. "Crime", "Transport", "Environment" - limit (number): 1-45, default 10 - offset (number): pagination offset, default 0 - response_format ('markdown' | 'json'): default 'markdown' Returns: { total, count, offset, has_more, next_offset, datasets: [{ id, dataset, publisher, category, api, licence, coverage, update_frequency }] } Examples: - "Where do I get EPC data?" -> query="EPC" - "What flood datasets are there?" -> query="flood" - "List every transport source" -> category="Transport", limit=20 Follow up with postcode_get_dataset for the full entry including API docs and the questions it answers.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Maximum results (default 10) |
| query | string | Free text matched against dataset name, publisher, category, API endpoint and the questions each dataset answers. Omit to list everything. |
| offset | integer | Results to skip, for pagination |
| category | string | Filter by category prefix, e.g. "Crime", "Transport", "Environment" |
| postcode* |
| string |
| A UK postcode, with or without a space, e.g. "SW11 1AA" or "m11ae" |
| categories | array | Which sections to fetch. Omit for all eleven. Fetching only what you need is faster and much smaller — e.g. ["crime","schools"] for a family-safety question. |
| include_sources | boolean | Append the publisher and licence of each dataset used (default false) |
| response_format | string | 'markdown' to read, 'json' for the full structured facts |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"postcode"
],
"properties": {
"postcode": {
"type": "string",
"maxLength": 10,
"minLength": 5,
"description": "A UK postcode, with or without a space, e.g. \"SW11 1AA\" or \"m11ae\""
},
"categories": {
"type": "array",
"items": {
"enum": [
"demographics",
"crime",
"deprivation",
"prices",
"broadband",
"mobile",
"noise",
"transport",
"amenities",
"schools",
"environment"
],
"type": "string"
},
"description": "Which sections to fetch. Omit for all eleven. Fetching only what you need is faster and much smaller — e.g. [\"crime\",\"schools\"] for a family-safety question."
},
"include_sources": {
"type": "boolean",
"default": false,
"description": "Append the publisher and licence of each dataset used (default false)"
},
"response_format": {
"enum": [
"markdown",
"json"
],
"type": "string",
"default": "markdown",
"description": "'markdown' to read, 'json' for the full structured facts"
}
}
}| response_format | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"default": 10,
"maximum": 45,
"minimum": 1,
"description": "Maximum results (default 10)"
},
"query": {
"type": "string",
"maxLength": 200,
"description": "Free text matched against dataset name, publisher, category, API endpoint and the questions each dataset answers. Omit to list everything."
},
"offset": {
"type": "integer",
"default": 0,
"maximum": 9007199254740991,
"minimum": 0,
"description": "Results to skip, for pagination"
},
"category": {
"type": "string",
"maxLength": 80,
"description": "Filter by category prefix, e.g. \"Crime\", \"Transport\", \"Environment\""
},
"response_format": {
"enum": [
"markdown",
"json"
],
"type": "string",
"default": "markdown"
}
}
}