uk-police-crime-mcp-server
Server Details
Search UK street crime, outcomes, stop and search, and neighbourhood teams (Scotland: BTP only).
- Status
- Healthy
- Uptime
- 99.9% over 22 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cyanheads/uk-police-crime-mcp-server
- GitHub Stars
- 1
- Server Listing
- @cyanheads/uk-police-crime-mcp-server
TDQS
Scored across 6 tools
The two search tools (ukcrime_search_crimes vs ukcrime_search_outcomes) overlap conceptually, but the descriptions explicitly disambiguate them (latest outcome of crimes recorded in a month vs outcomes recorded in a month). find_neighbourhood vs list_reference also touch the same force/neighbourhood vocabulary, though the descriptions clarify when to use each. Every tool has a distinct primary target.
All six tools share the ukcrime_ prefix and a clean verb_noun snake_case pattern: find_neighbourhood, get_crime_outcomes, list_reference, search_crimes, search_outcomes, search_stops. No mixed conventions or vague verbs.
Six tools is well within a healthy range and each maps to a distinct dataset or lookup (crimes, outcomes, stops, neighbourhoods, reference vocabulary, per-crime outcome history). Nothing feels redundant or missing at the count level.
The surface covers the core read-only workflows of the data.police.uk domain: searching crimes, outcomes, and stops, resolving neighbourhoods/forces, decoding reference vocabulary, and drilling into per-crime outcome history. Minor gaps exist (e.g., no explicit force-list or bulk/pagination helper beyond remaining_ids), but agents can work around them via the reference tool.
Available Tools
6 toolsukcrime_find_neighbourhoodFind UK Police NeighbourhoodARead-onlyIdempotentInspect
Find the police force and neighbourhood policing team for a point, or look one up by force and neighbourhood id. Returns the team's description, contact channels and police stations, its current priorities with the action taken, team members' ranks and names, and upcoming engagement events. include adds the boundary polygon, needed only to split a neighbourhood too large to search into smaller polygons: ukcrime_search_crimes, ukcrime_search_outcomes and ukcrime_search_stops take the neighbourhood directly through area 'neighbourhood'.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude, WGS84 decimal degrees, to look up by point (with lng). | |
| lng | No | Longitude, WGS84 decimal degrees, to look up by point (with lat). | |
| force | No | Force id such as 'leicestershire', or its name such as 'Leicestershire Police' (ukcrime_list_reference topic 'forces' lists both), to look up by id (with neighbourhood_id); case-insensitive, spaces, underscores and hyphens match each other, '&' matches 'and', and a trailing 'Police', 'Police Service' or 'Constabulary' is optional. | |
| include | No | Optional sections to load: 'priorities', 'team', 'events', 'boundary'. Omitted: priorities, team and events. [] loads none of them. | |
| neighbourhood_id | No | Neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', to look up by id (with force). Exact spelling first; after a miss, a unique case-insensitive catalog match is retried. |
Output Schema
| Name | Required | Description |
|---|---|---|
| gaps | No | The force's known coverage gaps, each ending with the date the table was verified. |
| team | No | Team members' ranks and names; present when include has 'team' and they loaded. |
| error | No | Present when the call failed. Absent on success. |
| force | No | The police force the neighbourhood belongs to, as published. |
| found | No | True when data.police.uk holds a neighbourhood team for the point or id. |
| events | No | Every upcoming engagement event the force published, soonest first and undated last; present when include has 'events' and they loaded. |
| notice | No | Parts that could not be loaded from data.police.uk, and how to retry. |
| boundary | No | The neighbourhood boundary; present when include has 'boundary' and it loaded. |
| guidance | No | Why nothing was found and what to try instead; present when found is false. |
| data_note | No | What these records can and cannot say; read it before drawing conclusions. |
| priorities | No | The team's current priorities, force-written; present when include has 'priorities' and they loaded. |
| attribution | No | Open Government Licence attribution for data.police.uk data. |
| events_total | No | Upcoming events published; every one is in events. |
| located_from | No | The point looked up, for a point lookup. |
| neighbourhood | No | The neighbourhood policing team and its public channels, as the force publishes them; an optional field is absent when unpublished, and all text is force-written. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds genuinely non-obvious behavior: the boundary polygon's purpose (splitting a neighbourhood too large to search) and the default section set. It does not describe failure behavior or what happens with no parameters, so it stops short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then returns, then the boundary/alternative-tool routing; every sentence carries information. It is dense but not padded, though the long enumeration of return contents could be tightened since an output schema already exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter, zero-required, dual-mode tool with an output schema and full annotations, the description covers both invocation modes, the include semantics, and sibling routing. The only gap is that it never says what happens when no lookup parameters are supplied, which matters given zero required parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so a baseline of 3 applies. The description goes beyond the schema by pairing lat/lng as the 'by point' mode and force/neighbourhood_id as the 'by id' mode, and by explaining the conditional need for the 'boundary' value of include.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource ('Find the police force and neighbourhood policing team') and immediately states the two lookup modes (point vs. force+neighbourhood id). It names sibling tools (ukcrime_search_crimes, ukcrime_search_outcomes, ukcrime_search_stops) and explains how they consume a neighbourhood, so the agent can separate this tool from its siblings without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly routes the agent: use this to resolve a neighbourhood, and note that the search_* siblings take the neighbourhood directly via area 'neighbourhood', plus that 'boundary' is needed only when splitting an oversized neighbourhood. It does not state when to prefer this over ukcrime_list_reference (it only cites list_reference as an id source), leaving one alternative implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ukcrime_get_crime_outcomesGet UK Crime Outcome HistoriesARead-onlyIdempotentInspect
Fetch the full police outcome history of up to 25 crimes per call by persistent_id — the 64-character id on crimes from ukcrime_search_crimes and ukcrime_search_outcomes. Accepts up to 1,000 raw elements or nonblank delimited tokens and 128,000 aggregate UTF-16 code units; remaining_ids carries unprocessed unique ids for the next call. Returns each crime with every outcome, oldest first, and lists the ids data.police.uk does not hold. Anti-social behaviour records carry no persistent id.
| Name | Required | Description | Default |
|---|---|---|---|
| persistent_ids | Yes | Persistent ids from ukcrime_search_crimes or ukcrime_search_outcomes: at most 1,000 raw array elements, 1,000 nonblank comma/whitespace-separated tokens before deduplication, and 128,000 aggregate UTF-16 code units. Ids are lower-cased, blanks and repeats dropped; every id is validated, the first 25 unique ids processed and the rest returned as remaining_ids. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| crimes | No | The crimes found, in the order their ids were given. |
| failed | No | Ids whose lookup still failed after retries for a reason other than a missing crime (outage, timeout, rate limit). Empty when none. |
| guidance | No | What to do about remaining_ids, not_found or failed; absent when every id resolved. |
| data_note | No | What these records can and cannot say; read it first. |
| not_found | No | Ids data.police.uk holds no crime for. |
| attribution | No | Open Government Licence attribution. |
| remaining_ids | No | Unprocessed ids in first-seen order; send these as persistent_ids on the next call. Empty when exhausted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/openWorld/idempotent, but the description adds substantial behavior beyond them: a 25-id processing cap per call, remaining_ids for continuation, 128,000 UTF-16 code unit and 1,000-element limits, oldest-first ordering, reporting of ids not held by data.police.uk, and the ASB-records-have-no-id caveat.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four densely packed sentences, each carrying distinct load (identity, limits, return shape, caveat). The essential scoping fact ('up to 25 per call') is front-loaded and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool with a full output schema, the description covers everything an agent needs: input origin, batching limits, pagination via remaining_ids, and edge cases. Return values need not be re-explained since an output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description nonetheless adds real meaning beyond the schema: what a persistent_id actually is (a 64-character id), where to obtain it (the two sibling search tools), and the processing/remaining_ids semantics that govern how the parameter is consumed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Fetch the full police outcome history') plus explicit scope ('up to 25 crimes per call by persistent_id'). It also distinguishes itself from siblings by naming ukcrime_search_crimes and ukcrime_search_outcomes as the sources of the ids it consumes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly establishes the context of use: this is the follow-up call that resolves ids obtained from the search tools into full outcome histories. It stops short of stating an explicit exclusion (e.g., when to prefer ukcrime_search_outcomes), so it is clear context without full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ukcrime_list_referenceList UK Police Reference DataARead-onlyIdempotentInspect
Decode the vocabulary the other ukcrime tools take: police force ids, crime category slugs, a force's neighbourhood ids, and data availability — the published months, and which forces published stop and search in each. Use it when a force, category, neighbourhood id or month is unknown; name_contains filters forces and neighbourhoods by name. The Metropolitan Police has about 680 neighbourhoods, so filter by name there; to get the force and neighbourhood covering a latitude and longitude, call ukcrime_find_neighbourhood instead.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Force id such as 'leicestershire', or its name such as 'Leicestershire Police'; case-insensitive, spaces, underscores and hyphens match each other, '&' matches 'and', and a trailing 'Police', 'Police Service' or 'Constabulary' is optional. Required for topic 'neighbourhoods'. On 'availability', where 'btp' (British Transport Police) is also accepted, adds the months this force did and did not publish stop and search. Not accepted on 'forces' or 'categories'. | |
| month | No | Month as YYYY-MM. Topic 'availability' only: return just that month's row. | |
| topic | Yes | What to list: 'forces' (force ids), 'categories' (crime category slugs), 'availability' (published months and stop-and-search publication), or 'neighbourhoods' (one force's neighbourhood ids; needs force). | |
| name_contains | No | Words that must all appear in the name, in any order — case, accents and punctuation ignored, so the value needs at least one letter or digit. Topics 'forces' and 'neighbourhoods' only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| force | No | Topic 'neighbourhoods': the force whose neighbourhoods are listed. |
| topic | No | The topic listed; its list field below is the one present. |
| forces | No | Topic 'forces': the forces data.police.uk lists, plus British Transport Police ('btp'), which ukcrime_search_stops takes with area 'force' and ukcrime_search_crimes with area 'force_unplaced'. |
| notice | No | Why a list is empty — a name filter that matched nothing, or a month that is not published — and what to do instead. |
| categories | No | Topic 'categories': every crime category. |
| attribution | No | Open Government Licence attribution for data.police.uk data. |
| availability | No | Topic 'availability': the published-month window and stop-and-search publication by month. |
| neighbourhoods | No | Topic 'neighbourhoods': the force's neighbourhoods, sorted by name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description adds genuinely useful operational context that annotations cannot: the Metropolitan Police has ~680 neighbourhoods so results should be name-filtered, which is a result-size/performance caveat an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, each earning its place: what it decodes, when to use it, and the large-result caveat plus alternative routing. The most important framing (this is the vocabulary/decoder tool) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't explain return shapes, and it covers everything else an agent needs: trigger conditions, topic meanings, the sibling alternative, and the Met Police filtering caveat. Nothing required to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so force/month/topic/name_contains semantics, patterns and cross-topic constraints are already fully documented in the schema. The description's mentions of name_contains and force-required-for-neighbourhoods largely restate that, so the baseline 3 is appropriate for a schema that does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (decode/lookup reference data) and enumerates the four resource types it returns (force ids, category slugs, neighbourhood ids, availability), which maps cleanly onto the topic enum. It also explicitly distinguishes itself from ukcrime_find_neighbourhood, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use it when a force, category, neighbourhood id or month is unknown' gives the precise trigger condition, and the closing sentence names the alternative tool and the exact scenario (lat/long to force/neighbourhood) that should select it instead. Both the when-to-use and when-to-use-something-else conditions are explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ukcrime_search_crimesSearch UK Street-Level CrimesARead-onlyIdempotentInspect
Search street-level crimes recorded in one month, or with month_from a range of up to 12 months, inside an area — a point with a 1-mile radius, a polygon, a snapped location_id from an earlier result, or a police neighbourhood — or list the crimes a force could not place on the map (area 'force_unplaced'). Returns the total, counts by category and by latest police outcome, the busiest map points, each month's total for a range, and a page of crimes, each with the persistent_id that ukcrime_get_crime_outcomes takes; for what police resolved in a month, whenever the crime was recorded, use ukcrime_search_outcomes. Locations are anonymised map points, not crime sites. data.police.uk can refuse an area holding more than about 10,000 crimes, whatever the category — then search smaller polygons.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude, WGS84 decimal degrees, for area 'point'. | |
| lng | No | Longitude, WGS84 decimal degrees, for area 'point'. | |
| area | Yes | Area to search: 'point' (lat and lng; a 1-mile radius), 'polygon' (polygon), 'location' (location_id), 'neighbourhood' (force and neighbourhood_id), or 'force_unplaced' (force alone: the crimes that force could not place on the map). An area field the chosen area does not use is rejected. | |
| force | No | Force id such as 'leicestershire', or its name such as 'Leicestershire Police' (ukcrime_list_reference topic 'forces' lists both); case-insensitive, spaces, underscores and hyphens match each other, '&' matches 'and', and a trailing 'Police', 'Police Service' or 'Constabulary' is optional. For area 'neighbourhood' (with neighbourhood_id) and 'force_unplaced' (alone), where 'btp' (British Transport Police) is also accepted. | |
| limit | No | Requested crimes on this page, 1–10,000; applied cap is at most 200. Default 25. | |
| month | No | Month as YYYY-MM, or the last month of the range with month_from. Omitted: the latest published month, echoed as month in the result. | |
| offset | No | Rows to skip before this page; pass next_offset from the previous result. Default 0. | |
| polygon | No | For area 'polygon': 3–2,500 vertices as { lat, lng } objects, or the string 'lat,lng:lat,lng:…'. The ring closes itself (the last vertex joins the first). [lng, lat] pairs are not accepted. | |
| category | No | Crime category slug such as 'burglary', or its display name such as 'Violence and sexual offences'; case-insensitive, and spaces, underscores and hyphens match each other ('vehicle_crime' finds 'vehicle-crime'). Omitted: every category (all-crime). ukcrime_list_reference topic 'categories' lists them. | |
| month_from | No | First month of a range, YYYY-MM, searched through month — up to 12 months, with a total for each in by_month. Omitted: month alone. | |
| location_id | No | For area 'location': location.location_id from an earlier result — one anonymised map point. | |
| neighbourhood_id | No | For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Exact spelling first; after a miss, a unique case-insensitive catalog match is retried. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | Page limit applied. |
| area | No | The area as the server searched it. |
| error | No | Present when the call failed. Absent on success. |
| month | No | The month searched, or the last month of the range, YYYY-MM. |
| shown | No | Rows on this page. |
| total | No | Crimes matched in the area over the month or range. |
| crimes | No | This page of matched crimes: oldest month first over a range, then by category, then location_id, then id. |
| notice | No | Defaulted month, coverage gaps, why a result is empty, and how to page on. |
| by_month | No | Crimes matched in each month of the range, oldest first; their totals sum to total. Present only when month_from was given. |
| category | No | The crime category searched. |
| data_note | No | What these records can and cannot say; read it first. |
| truncated | No | True when more rows remain after this page. |
| by_outcome | No | Matched crimes by latest police outcome, most first; anti-social behaviour is always '(not recorded)'. |
| month_from | No | First month of the range searched, YYYY-MM; present only when month_from was given. |
| attribution | No | Open Government Licence attribution. |
| by_category | No | Matched crimes by category slug, most first. |
| next_offset | No | Pass as offset for the next page; absent on the last page. |
| top_locations | No | Up to 10 map points holding the most matched crimes. Absent for area 'force_unplaced'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld), and the description adds genuine behavioral context beyond them: the upstream API can refuse a >10,000-crime area, and results are anonymised map points rather than actual crime sites. It stops short of describing pagination mechanics in prose, but the schema and output schema carry that load.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core search scope is front-loaded in the first sentence and no sentence is filler, but the em-dash-laden second and third sentences pack several distinct concerns (return shape, sibling routing, upstream cap) tightly enough to be hard to scan. Efficient but dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, five-mode search tool with an output schema, the description covers what an agent needs: area selection, range semantics, the persistent_id handoff, the sibling it is not, and the upstream size limitation. Return values are summarized rather than over-explained, which is appropriate given the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description still adds meaning by explaining how area modes map to parameters, that month/month_from form a range with per-month totals, and that each crime's persistent_id is the key consumed by ukcrime_get_crime_outcomes. That cross-tool linkage is information the schema alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource (street-level crimes) with precise scope: one month or a range up to 12 months, within one of five area modes. It explicitly separates itself from ukcrime_search_outcomes ('what police resolved in a month, whenever the crime was recorded'), so an agent can route correctly without opening the sibling schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use routing ('for what police resolved... use ukcrime_search_outcomes') plus an operational fallback: if data.police.uk refuses an area over ~10,000 crimes, search smaller polygons. This names both the alternative tool and the failure condition that should change the call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ukcrime_search_outcomesSearch UK Police OutcomesARead-onlyIdempotentInspect
List the police outcomes recorded in one month inside an area — a point with a 1-mile radius, a polygon, a location_id, or a neighbourhood — for crimes recorded that month or any earlier one. Returns the total, counts by crime category, outcome and the month each crime was recorded, and a page of outcomes, each with its crime and persistent_id. Use it for what police resolved in a month; ukcrime_search_crimes gives the latest outcome of the crimes recorded in a month instead. Court results are not published; the result says when a force publishes no outcomes.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude, WGS84 decimal degrees, for area 'point'. | |
| lng | No | Longitude, WGS84 decimal degrees, for area 'point'. | |
| area | Yes | Area to search: 'point' (lat and lng; a 1-mile radius), 'polygon' (polygon), 'location' (location_id), or 'neighbourhood' (force and neighbourhood_id). An area field the chosen area does not use is rejected. | |
| force | No | For area 'neighbourhood', with neighbourhood_id: a force id such as 'leicestershire', or its name such as 'Leicestershire Police' (ukcrime_list_reference topic 'forces' lists both); case-insensitive, spaces, underscores and hyphens match each other, '&' matches 'and', and a trailing 'Police', 'Police Service' or 'Constabulary' is optional. | |
| limit | No | Requested outcomes on this page, 1–10,000; applied cap is at most 200. Default 20. | |
| month | No | Month as YYYY-MM. Omitted: the latest published month, echoed as month in the result. | |
| offset | No | Rows to skip before this page; pass next_offset from the previous result. Default 0. | |
| polygon | No | For area 'polygon': 3–2,500 vertices as { lat, lng } objects, or the string 'lat,lng:lat,lng:…'. The ring closes itself (the last vertex joins the first). [lng, lat] pairs are not accepted. | |
| category | No | Count only outcomes for crimes in this category: a slug such as 'burglary' or a display name such as 'Violence and sexual offences'; case-insensitive, and spaces, underscores and hyphens match each other ('vehicle_crime' finds 'vehicle-crime'). Omitted or 'all-crime': every category. ukcrime_list_reference topic 'categories' lists them. | |
| location_id | No | For area 'location': location.location_id from an earlier result — one anonymised map point. | |
| neighbourhood_id | No | For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Exact spelling first; after a miss, a unique case-insensitive catalog match is retried. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | Page limit applied. |
| area | No | The area as the server searched it. |
| error | No | Present when the call failed. Absent on success. |
| month | No | The month searched — when the outcomes were recorded — YYYY-MM. |
| shown | No | Rows on this page. |
| total | No | Outcomes matched, after the category filter. |
| notice | No | Defaulted month, coverage gaps, why a result is empty, and how to page on. |
| category | No | The crime category counted; absent when every category was (no category, or 'all-crime'). |
| outcomes | No | This page of matched outcomes, sorted by the crime's month, newest first, then crime id. |
| data_note | No | What these records can and cannot say; read it first. |
| truncated | No | True when more rows remain after this page. |
| by_outcome | No | Matched outcomes by outcome, most first. |
| attribution | No | Open Government Licence attribution. |
| by_category | No | Matched outcomes by crime category, most first, then category in code-unit order. |
| next_offset | No | Pass as offset for the next page; absent on the last page. |
| by_crime_month | No | Matched outcomes by the month their crime was recorded, newest first. |
| unfiltered_total | No | Outcomes recorded in the area and month before the category filter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is covered. The description goes beyond them by describing the result shape (total, counts by category/outcome/month, a page of outcomes with crime and persistent_id) and by disclosing data-availability limits (no court results; a message when a force publishes no outcomes).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with purpose, then the return shape, then the sibling disambiguation and caveats. Every sentence carries information, though the middle sentence enumerating return fields is slightly dense when an output schema already exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, a fully documented input schema and read-only annotations, the description only needs to add the parts structured data cannot express — the routing rule versus the sibling, the month/outcome timing semantics, and publication caveats — and it does all three.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaning the schema doesn't: it clarifies that a point area is a 1-mile radius, that outcomes can attach to crimes recorded in that month or any earlier one, and that filtering is scoped by area and month. It does not add syntax detail beyond the schema, so it stops short of 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List the police outcomes recorded in one month inside an area') and enumerates the four supported area forms. It explicitly separates itself from the sibling ukcrime_search_crimes, so an agent can choose between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a direct routing rule: 'Use it for what police resolved in a month; ukcrime_search_crimes gives the latest outcome of the crimes recorded in a month instead.' That names the alternative and the discriminating condition. The note that court results are not published and that the result reports forces publishing no outcomes pre-empts dead-end calls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ukcrime_search_stopsSearch UK Police Stop and SearchARead-onlyIdempotentInspect
Search police stop and search records for one month, or with month_from a range of up to 12 months, inside an area — a point with a 1-mile radius, a polygon, a location_id from an earlier result, or a police neighbourhood — or across a whole force with area 'force', which includes stops the force could not place. Returns the total and counts by search type, self-defined and officer-defined ethnicity, outcome, object of search, legislation, age range, gender, whether the outcome was linked to the object of search, and whether more than outer clothing was removed, each month's total for a range, and a page of stops. filters narrow the counts and the page together, so filtering one field and reading another's breakdown gives a cross-tab. Forces skip months and some publish none; the result names each force it finds for the area that did not publish, with the months it skipped.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | No | Latitude, WGS84 decimal degrees, for area 'point'. | |
| lng | No | Longitude, WGS84 decimal degrees, for area 'point'. | |
| area | Yes | Area to search: 'point' (lat and lng; a 1-mile radius), 'polygon' (polygon), 'location' (location_id), 'neighbourhood' (force and neighbourhood_id), or 'force' (force alone: every stop the force published for the month or range, placed or not). An area field the chosen area does not use is rejected. | |
| force | No | Force id such as 'leicestershire', or its name such as 'Leicestershire Police' (ukcrime_list_reference topic 'forces' lists both); case-insensitive, spaces, underscores and hyphens match each other, '&' matches 'and', and a trailing 'Police', 'Police Service' or 'Constabulary' is optional. For area 'neighbourhood' (with neighbourhood_id) and 'force' (alone), where 'btp' (British Transport Police) is also accepted. | |
| limit | No | Requested stops on this page, 1–10,000; applied cap is at most 200. Default 15. | |
| month | No | Month as YYYY-MM, or the last month of the range with month_from. Omitted: the latest published month, echoed as month in the result. | |
| offset | No | Rows to skip before this page; pass next_offset from the previous result. Default 0. | |
| filters | No | Up to 8 filters, all of which a stop must match; they narrow the counts and the page together. Fields: type, self_defined_ethnicity, officer_defined_ethnicity, outcome, object_of_search, legislation, age_range, gender, outcome_linked_to_object_of_search, removal_of_more_than_outer_clothing. | |
| polygon | No | For area 'polygon': 3–2,500 vertices as { lat, lng } objects, or the string 'lat,lng:lat,lng:…'. The ring closes itself (the last vertex joins the first). [lng, lat] pairs are not accepted. | |
| month_from | No | First month of a range, YYYY-MM, searched through month — up to 12 months, with a total for each in by_month. Omitted: month alone. | |
| location_id | No | For area 'location': location.location_id from an earlier result — one anonymised map point. | |
| neighbourhood_id | No | For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Exact spelling first; after a miss, a unique case-insensitive catalog match is retried. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | Page limit applied. |
| area | No | The area as the server searched it. |
| error | No | Present when the call failed. Absent on success. |
| month | No | The month searched, or the last month of the range, YYYY-MM. |
| shown | No | Rows on this page. |
| stops | No | This page of matched stops, oldest first, then by location_id. |
| total | No | Stops matched after filters, over the month or range. |
| notice | No | Defaulted month, coverage gaps, why a result is empty, and how to page on. |
| by_type | No | Matched stops by search type, most first. |
| filters | No | Filters applied, case-insensitively; empty when none. |
| by_month | No | Stops matched in each month of the range, oldest first; their totals sum to total. Present only when month_from was given. |
| unplaced | No | Matched stops with no location — the force's unplaced stops, for area 'force'. |
| by_gender | No | Matched stops by gender, most first. |
| data_note | No | What these records can and cannot say; read it first. |
| truncated | No | True when more rows remain after this page. |
| by_outcome | No | Matched stops by outcome, most first; '(not recorded)' is often the largest. |
| month_from | No | First month of the range searched, YYYY-MM; present only when month_from was given. |
| attribution | No | Open Government Licence attribution. |
| next_offset | No | Pass as offset for the next page; absent on the last page. |
| by_age_range | No | Matched stops by age range, most first. |
| by_legislation | No | Matched stops by legislation, most first. |
| force_published | No | Whether every force found for the area (the one it names, or each located at a point, a polygon's centre and outermost vertices, or a location's map point) published stop and search this month, or in every month of a range: false when any month was missed. Otherwise absent when no force was found, when a month has no row in the publication list, or when none of those found is missing yet a polygon point could not be looked up. |
| unfiltered_total | No | Stops in the area over the month or range, before filters. |
| by_object_of_search | No | Matched stops by object of search, most first. |
| by_self_defined_ethnicity | No | Matched stops by ethnicity as the person defined it, most first. |
| by_officer_defined_ethnicity | No | Matched stops by ethnicity as the officer perceived it, most first. |
| by_outcome_linked_to_object_of_search | No | Matched stops by whether the outcome was linked to the object of search ('true', 'false' or '(not recorded)'), most first. |
| by_removal_of_more_than_outer_clothing | No | Matched stops by whether more than outer clothing was removed ('true', 'false' or '(not recorded)' where the force sent no value, as some do for vehicle-only searches), most first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/open-world, yet the description adds substantive behavioural context the annotations cannot: filters narrow counts and page together (enabling cross-tabs), and forces skip months or publish none, with the result naming each non-publishing force and its skipped months. That data-availability caveat is exactly the kind of extra disclosure this dimension rewards.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and area modes are front-loaded, but it is one sprawling sentence that enumerates every breakdown field (type, ethnicity, outcome, object, legislation, age, gender, linked, outer clothing) and the filter field list, content already supplied by the output schema and filters enum. Those clauses are bloat rather than earning their place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter tool with an output schema, the description covers what is needed to call it correctly: all five area modes and their required companions, month vs month_from range behaviour, filter interaction with counts and page, and the force-publication gaps that affect result interpretation. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameters are already fully documented and the baseline is 3. The description adds cross-field semantics not in the schema — that filtering one breakdown field while reading another yields a cross-tab, and that a range produces a by_month total per month — which raises it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Search) plus resource (police stop and search records) and pins down the scope: one month or a month_from range up to 12, inside a point/polygon/location_id/neighbourhood or across a whole force. An agent can distinguish this from ukcrime_search_crimes or ukcrime_search_outcomes purely from the text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the conditions under which each area mode applies (point needs lat/lng, range needs month_from, 'force' includes unplaced stops) and warns that forces skip months. It never explicitly names the sibling to use instead, so routing between it and ukcrime_search_crimes/search_outcomes is left to inference.
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.
6 tool updates
- Changed
ukcrime_find_neighbourhood3 fields changed- changed
Input schema / properties / neighbourhood_id / descriptionPrevious value: -"Neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', to look up by id (with force). Case-sensitive; only trimmed."New value: +"Neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', to look up by id (with force). Exact spelling first; after a miss, a unique case-insensitive catalog match is retried." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_lookup`: neither or both of lat+lng and force+neighbourhood_id are given, or half of a pair. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' (British Transport Police has no neighbourhoods). `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `upstream_unavailable`: data.police.uk is not answering. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `ambiguous_neighbourhood`: an exact neighbourhood request misses and more than one catalog id matches without case. `invalid_lookup`: neither or both of lat+lng and force+neighbourhood_id are given, or half of a pair. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' (British Transport Police has no neighbourhoods). `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `upstream_unavailable`: data.police.uk is not answering. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_lookup", - "unknown_force", - "rate_limited", - "pacer_shed", - "upstream_unavailable", - "retry_deadline_exceeded" -]New value: +[ + "ambiguous_neighbourhood", + "invalid_lookup", + "unknown_force", + "rate_limited", + "pacer_shed", + "upstream_unavailable", + "retry_deadline_exceeded" +]
- Changed
ukcrime_get_crime_outcomes9 fields changed- added
Input schema / properties / persistent_ids / anyOfAdded value: +[ + { + "description": "Comma- or whitespace-separated persistent ids, at most 1,000 nonblank tokens.", + "maxLength": 128000, + "type": "string" + }, + { + "description": "At most 1,000 raw elements and 128,000 aggregate UTF-16 code units.", + "items": { + "description": "One or more comma/whitespace-separated persistent ids.", + "type": "string" + }, + "maxItems": 1000, + "type": "array" + } +] - changed
Input schema / properties / persistent_ids / descriptionPrevious value: -"1–25 persistent ids from the persistent_id field of ukcrime_search_crimes or ukcrime_search_outcomes results. A comma- or space-separated string is also accepted; ids are lower-cased and repeats dropped."New value: +"Persistent ids from ukcrime_search_crimes or ukcrime_search_outcomes: at most 1,000 raw array elements, 1,000 nonblank comma/whitespace-separated tokens before deduplication, and 128,000 aggregate UTF-16 code units. Ids are lower-cased, blanks and repeats dropped; every id is validated, the first 25 unique ids processed and the rest returned as remaining_ids." - removed
Input schema / properties / persistent_ids / itemsRemoved value: -{ - "description": "A 64-character hexadecimal persistent id.", - "pattern": "^[0-9a-f]{64}$", - "type": "string" -} - removed
Input schema / properties / persistent_ids / maxItemsRemoved value: -25 - removed
Input schema / properties / persistent_ids / minItemsRemoved value: -1 - removed
Input schema / properties / persistent_ids / typeRemoved value: -"array" - changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "crimes", - "not_found", - "failed", - "attribution", - "data_note" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "remaining_ids", + "crimes", + "not_found", + "failed", + "attribution", + "data_note" + ] + }, + { + "required": [ + "error" + ] + } +] - changed
Output schema / properties / guidance / descriptionPrevious value: -"What to do about ids in not_found or failed; absent when every id resolved."New value: +"What to do about remaining_ids, not_found or failed; absent when every id resolved." - added
Output schema / properties / remaining_idsAdded value: +{ + "description": "Unprocessed ids in first-seen order; send these as persistent_ids on the next call. Empty when exhausted.", + "items": { + "description": "A validated persistent id.", + "type": "string" + }, + "type": "array" +}
- Changed
ukcrime_list_reference1 field changed- changed
Output schema / properties / neighbourhoods / items / properties / id / descriptionPrevious value: -"Id the other tools take as neighbourhood_id; case-sensitive."New value: +"Canonical id the other tools take as neighbourhood_id; exact spelling avoids a fallback lookup."
- Changed
ukcrime_search_crimes5 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Crimes on this page, 1–200. Default 25."New value: +"Requested crimes on this page, 1–10,000; applied cap is at most 200. Default 25." - changed
Input schema / properties / limit / maximumPrevious value: -200New value: +10000 - changed
Input schema / properties / neighbourhood_id / descriptionPrevious value: -"For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Case-sensitive; only trimmed."New value: +"For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Exact spelling first; after a miss, a unique case-insensitive catalog match is retried." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_area`: the area's required fields are missing, or a field it does not use is present. `month_not_published`: month or month_from is after the latest published month. `month_out_of_range`: month or month_from is before the 36-month window. `invalid_month_range`: month_from is after month, or the range spans more than 12 months. `unknown_category`: category matches no category slug or name. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' on area 'neighbourhood'. `unknown_neighbourhood`: the force has no neighbourhood with this id (ids are case-sensitive). `unknown_location`: data.police.uk holds no map point with this location_id. `area_too_large`: the area is too large to answer: data.police.uk can refuse one holding more than about 10,000 crimes. `range_too_large`: the range's months hold more records than one call keeps for a range. `range_incomplete`: the months of the range could not all be fetched within the time one call allows. `upstream_unavailable`: data.police.uk is not answering. `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `ambiguous_neighbourhood`: an exact neighbourhood request misses and more than one catalog id matches without case. `invalid_area`: the area's required fields are missing, or a field it does not use is present. `month_not_published`: month or month_from is after the latest published month. `month_out_of_range`: month or month_from is before the 36-month window. `invalid_month_range`: month_from is after month, or the range spans more than 12 months. `unknown_category`: category matches no category slug or name. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' on area 'neighbourhood'. `unknown_neighbourhood`: the exact neighbourhood request and any unique case-insensitive catalog match miss. `unknown_location`: data.police.uk holds no map point with this location_id. `area_too_large`: the area is too large to answer: data.police.uk can refuse one holding more than about 10,000 crimes. `range_too_large`: the range's months hold more records than one call keeps for a range. `range_incomplete`: the months of the range could not all be fetched within the time one call allows. `upstream_unavailable`: data.police.uk is not answering. `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_area", - "month_not_published", - "month_out_of_range", - "invalid_month_range", - "unknown_category", - "unknown_force", - "unknown_neighbourhood", - "unknown_location", - "area_too_large", - "range_too_large", - "range_incomplete", - "upstream_unavailable", - "rate_limited", - "pacer_shed", - "retry_deadline_exceeded" -]New value: +[ + "ambiguous_neighbourhood", + "invalid_area", + "month_not_published", + "month_out_of_range", + "invalid_month_range", + "unknown_category", + "unknown_force", + "unknown_neighbourhood", + "unknown_location", + "area_too_large", + "range_too_large", + "range_incomplete", + "upstream_unavailable", + "rate_limited", + "pacer_shed", + "retry_deadline_exceeded" +]
- Changed
ukcrime_search_outcomes7 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Outcomes on this page, 1–200. Default 20."New value: +"Requested outcomes on this page, 1–10,000; applied cap is at most 200. Default 20." - changed
Input schema / properties / limit / maximumPrevious value: -200New value: +10000 - changed
Input schema / properties / neighbourhood_id / descriptionPrevious value: -"For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Case-sensitive; only trimmed."New value: +"For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Exact spelling first; after a miss, a unique case-insensitive catalog match is retried." - changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "month", - "area", - "total", - "unfiltered_total", - "by_outcome", - "by_crime_month", - "outcomes", - "attribution", - "data_note", - "truncated", - "shown", - "cap" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "month", + "area", + "total", + "by_category", + "unfiltered_total", + "by_outcome", + "by_crime_month", + "outcomes", + "attribution", + "data_note", + "truncated", + "shown", + "cap" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / by_categoryAdded value: +{ + "description": "Matched outcomes by crime category, most first, then category in code-unit order.", + "items": { + "additionalProperties": false, + "description": "A value and its count.", + "properties": { + "count": { + "description": "Matched records.", + "type": "number" + }, + "value": { + "description": "As published; '(not recorded)' when absent.", + "type": "string" + } + }, + "required": [ + "value", + "count" + ], + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_area`: the area's required fields are missing, or a field it does not use is present. `month_not_published`: month is after the latest published month. `month_out_of_range`: month is before the 36-month window. `unknown_category`: category matches no category slug or name. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' (British Transport Police has no neighbourhoods). `unknown_neighbourhood`: the force has no neighbourhood with this id (ids are case-sensitive). `unknown_location`: data.police.uk holds no map point with this location_id. `area_too_large`: the area holds more than 10,000 outcomes, which data.police.uk refuses to answer. `upstream_unavailable`: data.police.uk is not answering. `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `ambiguous_neighbourhood`: an exact neighbourhood request misses and more than one catalog id matches without case. `invalid_area`: the area's required fields are missing, or a field it does not use is present. `month_not_published`: month is after the latest published month. `month_out_of_range`: month is before the 36-month window. `unknown_category`: category matches no category slug or name. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' (British Transport Police has no neighbourhoods). `unknown_neighbourhood`: the exact neighbourhood request and any unique case-insensitive catalog match miss. `unknown_location`: data.police.uk holds no map point with this location_id. `area_too_large`: the area holds more than 10,000 outcomes, which data.police.uk refuses to answer. `upstream_unavailable`: data.police.uk is not answering. `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_area", - "month_not_published", - "month_out_of_range", - "unknown_category", - "unknown_force", - "unknown_neighbourhood", - "unknown_location", - "area_too_large", - "upstream_unavailable", - "rate_limited", - "pacer_shed", - "retry_deadline_exceeded" -]New value: +[ + "ambiguous_neighbourhood", + "invalid_area", + "month_not_published", + "month_out_of_range", + "unknown_category", + "unknown_force", + "unknown_neighbourhood", + "unknown_location", + "area_too_large", + "upstream_unavailable", + "rate_limited", + "pacer_shed", + "retry_deadline_exceeded" +]
- Changed
ukcrime_search_stops6 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Stops on this page, 1–200. Default 15."New value: +"Requested stops on this page, 1–10,000; applied cap is at most 200. Default 15." - changed
Input schema / properties / limit / maximumPrevious value: -200New value: +10000 - changed
Input schema / properties / neighbourhood_id / descriptionPrevious value: -"For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Case-sensitive; only trimmed."New value: +"For area 'neighbourhood', with force: a neighbourhood id from ukcrime_list_reference topic 'neighbourhoods', or from ukcrime_find_neighbourhood for a point. Exact spelling first; after a miss, a unique case-insensitive catalog match is retried." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `invalid_area`: the area's required fields are missing, or a field it does not use is present. `month_not_published`: month or month_from is after the latest published month. `month_out_of_range`: month or month_from is before the 36-month window. `invalid_month_range`: month_from is after month, or the range spans more than 12 months. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' on area 'neighbourhood'. `unknown_neighbourhood`: the force has no neighbourhood with this id (ids are case-sensitive). `area_too_large`: the area holds more stops than data.police.uk will answer for. `range_too_large`: the range's months hold more records than one call keeps for a range. `range_incomplete`: the months of the range could not all be fetched within the time one call allows. `upstream_unavailable`: data.police.uk is not answering. `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `ambiguous_neighbourhood`: an exact neighbourhood request misses and more than one catalog id matches without case. `invalid_area`: the area's required fields are missing, or a field it does not use is present. `month_not_published`: month or month_from is after the latest published month. `month_out_of_range`: month or month_from is before the 36-month window. `invalid_month_range`: month_from is after month, or the range spans more than 12 months. `unknown_force`: force matches no listed force id or name, or more than one, or is 'btp' on area 'neighbourhood'. `unknown_neighbourhood`: the exact neighbourhood request and any unique case-insensitive catalog match miss. `area_too_large`: the area holds more stops than data.police.uk will answer for. `range_too_large`: the range's months hold more records than one call keeps for a range. `range_incomplete`: the months of the range could not all be fetched within the time one call allows. `upstream_unavailable`: data.police.uk is not answering. `rate_limited`: data.police.uk is rate-limiting this server for longer than this call can wait. `pacer_shed`: too many requests to data.police.uk are already queued in this server. `retry_deadline_exceeded`: data.police.uk did not answer within the time one call allows. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "invalid_area", - "month_not_published", - "month_out_of_range", - "invalid_month_range", - "unknown_force", - "unknown_neighbourhood", - "area_too_large", - "range_too_large", - "range_incomplete", - "upstream_unavailable", - "rate_limited", - "pacer_shed", - "retry_deadline_exceeded" -]New value: +[ + "ambiguous_neighbourhood", + "invalid_area", + "month_not_published", + "month_out_of_range", + "invalid_month_range", + "unknown_force", + "unknown_neighbourhood", + "area_too_large", + "range_too_large", + "range_incomplete", + "upstream_unavailable", + "rate_limited", + "pacer_shed", + "retry_deadline_exceeded" +] - changed
Output schema / properties / stops / items / properties / outcome / descriptionPrevious value: -"Outcome."New value: +"Outcome; a published false means Nothing found, while blank, null or absent is unrecorded."
6 tool updates
- First observed
ukcrime_find_neighbourhood - First observed
ukcrime_get_crime_outcomes - First observed
ukcrime_list_reference - First observed
ukcrime_search_crimes - First observed
ukcrime_search_outcomes - First observed
ukcrime_search_stops
Related MCP Connectors
Access street-level crime reports, stop and search data, and outcomes across UK police forces
UK Police MCP — wraps the UK Police Data API (free, no auth)
Search UK planning applications, entities, datasets, and conservation areas
Search UK companies, land registry prices, charities, OS locations, and traffic data
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides access to the police.uk API with 21 tools to query UK crime data, police forces, neighbourhoods, and stop-and-search incidents. Enables retrieval of street-level crimes, force details, neighbourhood teams, and policing priorities across England, Wales, and Northern Ireland.215 npm2MIT
- AlicenseNot gradedqualityBmaintenanceWraps the UK Police Data API to enable querying crime data, police forces, and other UK police information through natural language.8 npmMIT
- AlicenseAqualityCmaintenanceUS crime safety scores, recent incidents, neighborhood demographics, rent data, and registered-offender search by address. Free tier available.4MIT

Zyfy MCP Serverofficial
AlicenseAqualityCmaintenanceEnables natural language queries about UK postcodes and vehicles, including flood risk, crime rate, broadband coverage, property prices, MOT history, and ULEZ compliance.413 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.