# InstaMaps MCP server: full reference > Location tools for lists: geocode with a confidence per row, measure straight-line and road distances, plan multi-driver routes, check official zones, flood and crime risk, live flood and storm warnings, find places nearby, ask questions of a whole table, and keep layered maps. Built for spreadsheets and agents. - Server: https://get-instamaps.com/mcp (streamable-http; OAuth 2.1: sign in with Google (no API key)) - Free: 5,000 tool calls a day per person, reset at midnight UTC; a call counts once however many rows it carries; a sheet by reference is one call; checking a job is free. - Coverage: Strongest in the US and Great Britain (our own address index, roads and official data); placement works worldwide. - Add it: claude mcp add --transport http instamaps https://get-instamaps.com/mcp - Version 0.6.0; examples captured 2026-10-13 from the live server ## What every answer guarantees - Nothing is dropped: every row sent comes back, in order, under your own id; rows that cannot be placed or answered say why. An answer that would lose rows fails loudly instead. - Every row carries confidence {level: high | medium | low, score, basis}; basis is a stable code (rooftop, postcode_centre, not_placed…) and the answer's confidence object says what each basis present means and what to do about it. - Every row carries record_key, the same place ID from every tool, so answers from different tools join on it. - Every answer ends with a run block: when, how many rows, sources with their dates, the confidence counts, calls used and left today, and a run_id that any tool can take as source {run} and render_map as from_run. - Lists by reference: pass a Google Sheet, a Drive file or a run_id instead of typing rows. Every tool but one only reads; write_to_sheet puts an answer into the sheet as new dated columns or a new tab, never overwriting. - No vendor or model names in answers; every source is named with its date. ## Choosing a tool - geocode_batch: Turn a list of addresses, business names, postcodes or coordinates into points, with a confidence and the address parts for every row. - filter_by_location: Which records are within N miles or km of one or more sites, or the nearest sites to each record, by straight-line distance. - ask_table: Answer a plain-English question about a whole table (filters, counts, distances to a named place or a second list), showing how it read the question. - get_road_distances: Road distance and drive time for each from–to journey, on our own road network, with typical weekday traffic. - plan_routes: Split up to 100 stops across up to 10 drivers from one depot, in the best order on real roads, with Google Maps links per driver. - get_travel_time_area: The area reachable from a place within N minutes by car, on foot or by bike, and which of your records fall inside each band. - get_location_facts: The official areas each address falls in: US census tract, income level, county, metro, HUBZone, Opportunity Zone, USDA eligibility, FEMA flood zone; GB conservation area, listed buildings, nearest UPRN, England flood zone. - get_area_risk: One risk fact per place: recorded crime nearby (England and Wales) with the commonest types, flood zone (England, US), or FEMA natural-hazard rating (US). - find_postcodes_in_radius: Every US ZIP code, or UK postcode sector or district, within a radius of a place, nearest first. - get_live_hazards: Warnings and events in force now: England's flood warnings, US weather warnings, and worldwide earthquake shaking, hurricanes, floods, wildfires and volcanoes, with kind, level, area, times and outline. - check_live_hazards: Which of your places are inside or near a warning or event now (or were hit by one), with insured values added up. - find_nearby: The nearest, the count, or a list of places of a kind (stations, schools, supermarkets, pharmacies…) around each address. - find_official_places: The official record: A&E departments, hospitals, GP practices, care homes and dentists with CQC ratings, NHS pharmacies, food hygiene ratings; or the record of the business at each row. - render_map: A hosted, layered map to keep or share: pins, lines or areas, colours by field, a legend, GeoJSON and KML. - update_map: Change a kept map in place: add or remove layers, move or add pins, recolour, rename; the link stays the same and earlier versions are kept. - get_map: Look at a kept map from an earlier conversation: its layers, pin ids and fields. With no map named, list the person's own maps, including the ones they made in the InstaMaps Google Sheets add-on. - combine_runs: Join two to six kept runs on the place ID every tool returns (record_key) and say what changed between them. - get_job: How far a background job has got: status, rows done, minutes left, and its run_id when done. - write_to_sheet: Put an earlier answer into a Google Sheet: new dated columns beside the rows it came from, or a new tab. Never overwrites a cell. The only tool that writes. ## geocode_batch: Geocode a list of addresses Turn a list of addresses, business names, postcodes or coordinates into points, with a confidence and the address parts for every row. Docs: https://get-instamaps.com/mcp-server/tools/geocode_batch Use when: - A list of addresses needs coordinates before anything else happens - You need to know how sure each placement is before trusting it - You want a sheet-ready table (format: "csv") with city, county, state, postcode, UK council and UPRN Not for: - Distances or "who is near what": filter_by_location, get_road_distances - Finding businesses of a kind around a place: find_nearby Usual chain: geocode_batch → filter_by_location or ask_table → plan_routes or render_map Coverage: Worldwide; strongest in the US and Great Britain (house-level address data); council and UPRN in Great Britain. Measured: - US benchmark of 1,150 real addresses from business lists (12 Oct 2026): 873 placed; 636 of those could be checked against an independent reference, and 627 (98.6%) were within 150 m of it. - Rows it cannot place come back unplaced with a plain reason (for example "street not in our index"), never as a guess. Sources: - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Inputs: - addresses (array, up to 100): Addresses, one per row. - records (array, up to 100): Or rows with your own ids. - format (string, default "json", one of json | csv): csv: also return every row as CSV text (csv), one line per row in the order sent, to save as a file in Drive or paste into a sheet. - columns (array): The fields for the CSV and for write_to_sheet, in order (CSV default: status, lat, lng, precision, confidence, reason, house_number, street, city, county, state, postcode, country, council, uprn, record_key; write_to_sheet default: lat, lng, status, address, city, county, state, postcode, country, precision, confidence). ID and input always lead the CSV. council (Great Britain: the local authority) and uprn (Great Britain: the nearest UPRN to a pin on a building, within 15 m) are blank elsewhere. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 100 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: Place up to 100 addresses in one call. Each record comes back with a status (placed, review, unplaced), the location and its precision (rooftop, interpolated, street, postcode, town), a confidence with the evidence behind it (the score is how often an answer that sure was right when measured; the same input always gets the same answer), the address quality, the admin parts (street, city, county, state, postcode, country), a stable record_key and the map version, and where one is close enough to be sure, the building at the point (residential or not: house, business, farm…). Coordinates in any common format ("53.8008, -1.5491", 51°30'03"N 0°07'40"W, "48.8584 N 2.2945 E"), or records with lat and lng, are placed as given and come back with the address at the point (nearest_address and the admin parts): this is also how to turn coordinates into addresses. Flats, units and suites are matched to their building. Every row carries its address parts (admin: house number, street, city, county, state, postcode, country); format "csv" also returns them as CSV to save in Drive or a sheet, and write_to_sheet puts them in the sheet as columns. Every row sent comes back in the order sent: unplaced rows with the reason, and rows past 100 as not looked up. Example request: ```json { "records": [ { "id": "hq", "address": "10 Downing Street, London SW1A 2AA" }, { "id": "wh", "address": "1600 Pennsylvania Ave NW, Washington DC 20500" }, { "id": "x", "address": "asdfgh" } ] } ``` Answer headline: 3 rows: 2 placed, 0 to review, 1 unplaced · 2 of 3 high confidence (0 medium, 1 low). Caveats: not placed (1 row). Answer (trimmed): ```json { "confidence": { "summary": "2 of 3 high confidence (0 medium, 1 low). Caveats: not placed (1 row).", "levels": { "high": 2, "medium": 0, "low": 1 }, "caveats": [ { "basis": "not_placed", "level": "low", "rows": 1, "ids": [ "x" ], "meaning": "This row could not be placed.", "next": "Leave it out of totals, say so, and ask the user for a postcode or coordinates." } ] }, "records": [ { "id": "hq", "input": "10 Downing Street, London SW1A 2AA", "record_key": "rk1_e9ec1ea25045e3a5e393", "address_quality": { "value": "full_street", "basis": "rule" }, "status": "placed", "location": { "value": { "lat": 51.5034878, "lng": -0.1276965 }, "precision": "rooftop", "confidence": { "value": 0.95, "basis": "rule", "evidence": [ "named site matched (10 Downing Street)", "house number 10 matched", "street matched (Downing Street)", "… 5 more" ] } }, "admin": { "value": { "house_number": "10", "street": "Downing Street", "city": "London", "county": "Greater London", "state": "England", "postcode": "SW1A 2AA", "country": "GB", "council": "Westminster" }, "basis": "rule", "evidence": [ "open map data", "council from the official postcode directory" ] }, "map_version": "osm-2026-10-03", "uprn": { "value": "100023336956", "distance_m": 6, "basis": "nearest" }, "confidence": { "level": "high", "score": 0.95, "basis": "geocode_checked", "why": "rooftop" } }, { "id": "wh", "input": "1600 Pennsylvania Ave NW, Washington DC 20500", "record_key": "rk1_0579e7bc70379e42dce9", "address_quality": { "value": "full_street", "basis": "rule" }, "status": "placed", "location": { "value": { "lat": 38.8976387, "lng": -77.0365525 }, "precision": "rooftop", "confidence": { "value": 0.95, "basis": "rule", "evidence": [ "house number 1600 matched", "street matched (Pennsylvania Avenue Northwest)", "postcode agrees (20500)", "… 4 more" ] } }, "admin": { "value": { "house_number": "1600", "street": "Pennsylvania Avenue Northwest", "city": "Washington", "county": "District of Columbia", "state": "DC", "postcode": "20500", "country": "US" }, "basis": "rule", "evidence": [ "open map data" ] }, "map_version": "osm-2026-10-03", "confidence": { "level": "high", "score": 0.95, "basis": "geocode_checked", "why": "rooftop" } }, { "id": "x", "input": "asdfgh", "record_key": "rk1_8588310a98676af6e225", "address_quality": { "value": "town_only", "basis": "rule" }, "status": "unplaced", "location": { "value": null, "precision": "none", "confidence": { "value": 0.2, "basis": "rule", "evidence": [ "town differs (The Municipal District of Newcastle West on the map)", "position: the centre of the town", "nothing about it matches the input" ] }, "why": "unreadable address: no street, town or postcode we recognise" }, "admin": { "value": null, "basis": "rule", "evidence": [ "open map data" ] }, "map_version": "osm-2026-09-19", "confidence": { "level": "low", "score": 0.2, "basis": "not_placed", "why": "unreadable address: no street, town or postcode we recognise" } } ], "summary": { "records": 3, "status": { "placed": 2, "review": 0, "unplaced": 1 }, "precision": { "rooftop": 2, "none": 1 }, "vs_paid_reference": null, "vs_live_product": null, "declined_but_placed_by": { "paid_reference": [], "live_product": [] }, "sent": 3 }, "ms": 1875, "run": { "tool": "geocode_batch", "at": "2026-10-13T15:59:09.444Z", "rows": 3, "placed": 2, "review": 0, "unplaced": 1, "not_placed": 1, "sources": [ { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "run_id": "run_30182f16c73e3d50", "confidence": { "high": 2, "medium": 0, "low": 1 } } } ``` ## filter_by_location: Filter records by distance to sites Which records are within N miles or km of one or more sites, or the nearest sites to each record, by straight-line distance. Docs: https://get-instamaps.com/mcp-server/tools/filter_by_location Use when: - "Customers within 25 miles of our depots" - The nearest store or branch to each customer - Large lists where speed matters more than road distance Not for: - Driving distance or time: get_road_distances - Everything reachable in N minutes: get_travel_time_area - Every ZIP or postcode inside a radius: find_postcodes_in_radius Usual chain: geocode_batch (or rows with lat/lng) → filter_by_location → plan_routes or render_map Coverage: Worldwide (straight-line distance). Sources: - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: straight-line (great-circle) distance Inputs: - records (array): The list to filter: {id, address} or {id, lat, lng}. - sites (array, up to 25): Depots, stores, offices: {id, address} or {id, lat, lng}. - within_miles (number): Keep records within this many miles of any site. - within_km (number): Or the same in kilometres. - nearest_n (integer): Also list the N nearest records to each site. - render (boolean, default false): Also keep the map (the sites, their radius and the records): a link to share, GeoJSON and KML. - title (string): The kept map's title when render is on. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 200 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. - sites_source (object): The sites by reference, the same way as source. Full description as served: Which records are within a distance of any site, the nearest site to each record, and/or the N nearest records to each site. Records and sites can be addresses (placed first, up to 100 addresses per call) or lat/lng (up to 2000 records, 25 sites). Distances are straight-line (great-circle), not driving. Every record says which site it was measured to and how far; records held for review are flagged and records that could not be placed are listed, never silently counted in or out. Over 200 records the answer is compact: every record's nearest site as [id, site, miles], full detail for the matches only. The map shows in the chat by itself. Set render to true only when the user wants to keep or share the map: it returns a link, GeoJSON and KML, and update_map can change it later. Example request: ```json { "records": [ { "id": "a", "name": "Leeds Town Hall", "address": "Leeds Town Hall, Leeds LS1 3AD" }, { "id": "b", "name": "York Minster", "address": "York Minster, York YO1 7HH" }, { "id": "c", "name": "Manchester Piccadilly", "address": "Manchester Piccadilly station, Manchester M1 2BN" } ], "sites": [ { "id": "depot", "name": "Leeds depot", "address": "Leeds LS1 4AP" } ], "within_miles": 30 } ``` Answer headline: within 30 miles of the site; straight-line distance, not driving distance. 2 of 3 placed records match · 2 of 3 high confidence (1 medium, 0 low). Caveats: placed, less sure (1 row). Answer (trimmed): ```json { "confidence": { "summary": "2 of 3 high confidence (1 medium, 0 low). Caveats: placed, less sure (1 row).", "levels": { "high": 2, "medium": 1, "low": 0 }, "caveats": [ { "basis": "geocode_low", "level": "medium", "rows": 1, "ids": [ "c" ], "meaning": "Placed, with lower confidence than usual.", "next": "Mention it may be off, and confirm it if the answer depends on it." } ] }, "reading": "within 30 miles of the site; straight-line distance, not driving distance", "matched": [ "a", "b" ], "records": [ { "id": "a", "label": "Leeds Town Hall, Leeds LS1 3AD", "location": { "lat": 53.8002679, "lng": -1.5497207 }, "nearest_site": { "id": "depot", "distance_miles": 0.4, "distance_km": 0.7 }, "within": true, "sites_within": [ "depot" ], "placement": { "status": "placed", "precision": "rooftop", "confidence": 0.92, "map_version": "osm-2026-10-03" }, "record_key": "rk1_497c1fa89025ba5bc79f", "confidence": { "level": "high", "score": 0.92, "basis": "geocode_checked", "why": "rooftop" } }, { "id": "b", "label": "York Minster, York YO1 7HH", "location": { "lat": 53.9623561, "lng": -1.0820834 }, "nearest_site": { "id": "depot", "distance_miles": 22.5, "distance_km": 36.2 }, "within": true, "sites_within": [ "depot" ], "placement": { "status": "placed", "precision": "rooftop", "confidence": 0.92, "map_version": "osm-2026-10-03" }, "record_key": "rk1_fb67d1e967e22b14fe65", "confidence": { "level": "high", "score": 0.92, "basis": "geocode_checked", "why": "rooftop" } }, { "id": "c", "label": "Manchester Piccadilly station, Manchester M1 2BN", "location": { "lat": 53.4778949, "lng": -2.2310037 }, "nearest_site": { "id": "depot", "distance_miles": 35.3, "distance_km": 56.8 }, "within": false, "sites_within": [], "placement": { "status": "placed", "precision": "postcode", "confidence": 0.75, "map_version": "osm-2026-10-03", "why": "placed in the postcode the input gives; the exact building is not certain" }, "record_key": "rk1_daeb813ec04d00f1c1fc", "confidence": { "level": "medium", "score": 0.75, "basis": "geocode_low", "why": "postcode" } } ], "held_for_review": [], "could_not_place": [], "sites": [ { "id": "depot", "location": { "lat": 53.795472, "lng": -1.555729 }, "placement": { "status": "placed", "precision": "postcode" } } ], "sites_not_placed": [], "run": { "tool": "filter_by_location", "at": "2026-10-13T15:59:12.161Z", "sources": [ { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "straight-line (great-circle) distance", "run_id": "run_2133642d49110140", "confidence": { "high": 2, "medium": 1, "low": 0 } } } ``` ## ask_table: Ask a question about a table Answer a plain-English question about a whole table (filters, counts, distances to a named place or a second list), showing how it read the question. Docs: https://get-instamaps.com/mcp-server/tools/ask_table Use when: - "Overdue or fault jobs within 5 miles of the Enfield depot" - Counts and breakdowns over thousands of rows without writing formulas - A question mixing column filters with places Not for: - Placing addresses: geocode_batch - Planning visits: plan_routes Coverage: Any table; place questions use our UK and US geography. Measured: - A question that matches nothing says which condition emptied it and what the table holds instead (for example "Status holds: Fault (7), OK (7), Overdue (6)"). Sources: - the rows you sent (as sent) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: as the reading says Inputs: - question (string, required): The question, as a person would ask it. - records (array, up to 5000): The table as row objects (keys are the column names). - headers (array): Or the column names… - rows (array, up to 5000): …and the rows as arrays in the same order. - mode (string, default "rows", one of rows | match | why): - reference_records (array): Optional second list for two-list questions (depots, competitors, stores). - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: Answer a plain-English question about a table of rows (up to 5,000): filters ("open jobs in Leeds due this week", "accounts with no rep"), place questions ("customers within 5 miles of Manchester", "sites with 3+ pharmacies within 1 km", "in a flood zone", "high crime areas"), ranking, counts and group-bys ("homes by agent", "average price by area"), and two-list questions with reference_records ("customers within 10 km of any depot in the reference list"). Deterministic: the question is read into rules and tools, never answered by a model making up values, and `reading` says exactly how it was read. The first 200 matching rows come back in mode rows; past that use mode match. A zero result comes with a diagnosis (which part emptied it and the nearest non-empty reading). mode rows (default) returns the matching rows; match returns one TRUE/FALSE per input row in order (best for big tables: join it back in your own code); why returns the reading. Rows without lat/lng are placed from an address column when the question needs places. Place tools (nearby, crime, busy) cover the UK; flood covers England and the US. Example request: ```json { "question": "Which accounts have annual revenue over 50k?", "records": [ { "Account": "Rice University", "Address": "6100 Main St Houston TX 77005", "Annual revenue": 82000 }, { "Account": "Museum of Fine Arts", "Address": "1001 Bissonnet St Houston TX 77005", "Annual revenue": 23000 }, { "Account": "Toyota Center", "Address": "1510 Polk St Houston TX 77002", "Annual revenue": 61000 } ] } ``` Answer headline: Read as: Annual revenue > 50,000. 2 of 3 rows match Answer (trimmed): ```json { "confidence": { "summary": "All 1 high confidence.", "levels": { "high": 1, "medium": 0, "low": 0 } }, "question": "Which accounts have annual revenue over 50k?", "reading": "Annual revenue > 50,000", "matched": 2, "total": 3, "values": [ [ "Account", "Address", "Annual revenue" ], [ "Rice University", "6100 Main St Houston TX 77005", 82000 ], [ "Toyota Center", "1510 Polk St Houston TX 77002", 61000 ] ], "diagnosis": [], "tools": [], "reading_confidence": { "level": "high", "score": 0.9, "basis": "reading_sure" }, "best_guess": false, "trace_id": "ye0prG6E8a4u5MgB2v7N", "ms": 729, "run": { "tool": "ask_table", "at": "2026-10-13T15:59:13.629Z", "question": "Which accounts have annual revenue over 50k?", "rows": 3, "matched": 2, "sources": [ { "name": "the rows you sent", "as_of": "as sent" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "as the reading says", "confidence": { "high": 1, "medium": 0, "low": 0 } } } ``` ## get_road_distances: Road distance and drive time for journeys Road distance and drive time for each from–to journey, on our own road network, with typical weekday traffic. Docs: https://get-instamaps.com/mcp-server/tools/get_road_distances Use when: - Mileage claims and expense checks - Depot-to-customer drive times - Comparing journeys where straight-line distance would mislead Not for: - Visiting many stops in the best order: plan_routes - Everything reachable in N minutes: get_travel_time_area Coverage: Great Britain and the US by road; elsewhere straight line, labelled as such. Sources: - InstaMaps roads: OpenStreetMap routed with Valhalla (GB and US) (2026-10-08) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: road distance and drive time, normal traffic; straight line where a journey says so Inputs: - journeys (array, up to 100): {id, from, to}; from/to are text (address, postcode) or {lat, lng}. - region (string, one of uk | us): Optional; worked out from the postcodes when left out. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 100 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - traffic (string, default "weekday", one of weekday | free_flow): weekday (default): road times with the area's measured weekday slowdown (DfT delay on local 'A' roads by council and on motorways in Great Britain; the Urban Mobility Report's Travel Time Index by US urban area). free_flow: empty roads. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: Road miles, km and drive time for up to 100 journeys per call, on our own routing (Great Britain and US roads, normal traffic, no live traffic). Ends can be addresses, UK postcodes or districts (CO10), US addresses, or lat/lng. Every journey also gets the straight-line miles; a journey with no road route (Northern Ireland, an island without a bridge) is measured in a straight line and says so in `note`. The summary has the total road miles (for mileage claims) and the total with straight-line journeys included. Example request: ```json { "journeys": [ { "id": "1", "from": "Leeds LS1 4AP", "to": "York YO1 7HH" }, { "id": "2", "from": "Austin TX 78701", "to": "Dallas TX 75201" } ] } ``` Answer headline: 2 journeys: 2 by road (228.3 road miles) · 0 of 2 high confidence (2 medium, 0 low). Caveats: postcode centre (2 rows); street or named place (1 row). Answer (trimmed): ```json { "confidence": { "summary": "0 of 2 high confidence (2 medium, 0 low). Caveats: postcode centre (2 rows); street or named place (1 row).", "levels": { "high": 0, "medium": 2, "low": 0 }, "caveats": [ { "basis": "postcode_centre", "level": "medium", "rows": 2, "ids": [ "1", "2" ], "meaning": "The street address was not matched, so the row sits at its postcode centre, usually within 100-300 m of the real spot.", "next": "Fine for nearest-place questions and distances over a kilometre; check it before relying on street-level detail." }, { "basis": "named_place", "level": "medium", "rows": 1, "ids": [ "1" ], "meaning": "Placed on a street or a named place; no house number was given, so it is not a doorstep point.", "next": "Fine for area questions. For doorstep precision, send a house number or coordinates." } ] }, "region": "uk", "engine": "owned", "traffic": { "model": "weekday", "note": "drive_minutes are weekday estimates: free-flow road time × the measured slowdown where each trip starts (free_flow_minutes and traffic_factor per journey). Weekday estimate: free-flow road times × 1.41 for short trips in Leeds (local A roads), easing to × 1.21 on trips of an hour or more (DfT 2025 average delay on local 'A' roads and motorways)." }, "summary": { "journeys": 2, "by_road": 2, "straight_line_only": 0, "not_found": 0, "total_road_miles": 228.3, "total_miles": 228.3 }, "journeys": [ { "id": "1", "from": "Leeds LS1 4AP", "to": "York YO1 7HH", "from_key": "rk1_5fac800fc81c4adfc5dc", "to_key": "rk1_d1ee5931d1454ef356c3", "ok": true, "road_miles": 31.6, "road_km": 50.8, "drive_minutes": 46, "free_flow_minutes": 35, "traffic_factor": 1.32, "straight_miles": 22.5, "note": null, "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "at the centre of LS1 4AP", "also": [ "named_place" ] } }, { "id": "2", "from": "Austin TX 78701", "to": "Dallas TX 75201", "from_key": "rk1_04eee8f4823eb361af87", "to_key": "rk1_0b07c9b29d3f2465f7a7", "ok": true, "road_miles": 196.7, "road_km": 316.5, "drive_minutes": 197, "free_flow_minutes": 168, "traffic_factor": 1.17, "straight_miles": 182.5, "note": null, "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "the centre of ZIP 78701" } } ], "run": { "tool": "get_road_distances", "at": "2026-10-13T15:59:17.217Z", "rows": 2, "answered": 2, "sources": [ { "name": "InstaMaps roads: OpenStreetMap routed with Valhalla (GB and US)", "as_of": "2026-10-08" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "road distance and drive time, normal traffic; straight line where a journey says so", "run_id": "run_332ad58746be4309", "confidence": { "high": 0, "medium": 2, "low": 0 } } } ``` ## plan_routes: Plan routes for one or more drivers Split up to 100 stops across up to 10 drivers from one depot, in the best order on real roads, with Google Maps links per driver. Docs: https://get-instamaps.com/mcp-server/tools/plan_routes Use when: - A day of deliveries, installs or visits - More than 10 stops (the Google Maps app limit) - Work that must fit a shift, with time at each stop Not for: - Single journeys: get_road_distances - Just the nearest site to each customer: filter_by_location Usual chain: geocode_batch (optional) → plan_routes → render_map (to keep the routes) Coverage: Great Britain and the US on our roads; elsewhere straight-line estimates, labelled. Measured: - Each driver past the daily driving limits (EU/UK 9 h, US 11 h) is warned; low bridges under 4.6 m on a driver's roads are listed (OpenStreetMap, advisory). Sources: - InstaMaps roads: OpenStreetMap routed with Valhalla (GB and US) (2026-10-08) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: road drive times, normal traffic Inputs: - depot (object, required): Where the drivers start: an address or {lat, lng}. - stops (array, up to 100): Addresses, or {id, name, address} / {id, name, lat, lng}. name labels the stop on the map and in the plan. - drivers (integer, default 1): - return_to_depot (boolean, default true): - shift_hours (number, default 8): - service_minutes (number, default 10): Time spent at each stop. - render (boolean, default false): Also keep the map: a link to share with the drivers, GeoJSON and KML. - title (string): The kept map's title when render is on. - traffic (string, default "weekday", one of weekday | free_flow): weekday (default): road times with the area's measured weekday slowdown (DfT delay on local 'A' roads by council and on motorways in Great Britain; the Urban Mobility Report's Travel Time Index by US urban area). free_flow: empty roads. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: Split up to 100 stops across up to 10 drivers from one depot and put each driver's stops in the best order on real roads (Great Britain and US), within a shift length including time at each stop. Each driver gets google_maps_links: the day as chained Google Maps links of up to 9 stops each, every link starting where the last one ended (the Maps app takes about 10 stops a route), so a driver opens the first and then the next; plus google_maps_link_all_stops, one link with every stop, for a desktop browser. Stops that do not fit or cannot be reached come back in `unassigned` with the reason. A driver over the daily driving limits (EU/UK 9 hours, US 11) gets driving_limit_warning; low bridges under 4.6 m near a driver's road come back as low_bridges (advisory). The map with each driver's route shows in the chat by itself. Set render to true only when the user wants to keep or share the map: it returns a link, GeoJSON and KML, and update_map can change it later. A kept route map carries each driver's Google Maps links. Example request: ```json { "depot": "Canning Town, London E16 1DQ", "stops": [ { "id": "0", "address": "Stratford Station, London E15 1AZ" }, { "id": "1", "address": "Hackney Central, London E8 1LL" }, { "id": "2", "address": "Bethnal Green Road, London E2 6AH" }, { "id": "3", "address": "Bow Road, London E3 4DH" }, { "id": "4", "address": "Leyton High Road, London E10 5NA" } ], "drivers": 1 } ``` Answer headline: 5 stops across 1 driver(s) · 1 of 5 high confidence (4 medium, 0 low). Caveats: street or named place (4 rows). Answer (trimmed): ```json { "confidence": { "summary": "1 of 5 high confidence (4 medium, 0 low). Caveats: street or named place (4 rows).", "levels": { "high": 1, "medium": 4, "low": 0 }, "caveats": [ { "basis": "named_place", "level": "medium", "rows": 4, "ids": [ "4", "1", "2", "… 1 more" ], "meaning": "Placed on a street or a named place; no house number was given, so it is not a doorstep point.", "next": "Fine for area questions. For doorstep precision, send a house number or coordinates." } ] }, "traffic": { "model": "weekday", "area": "Newham (local A roads)", "note": "Weekday estimate: free-flow road times × 1.45 for short trips in Newham (local A roads), easing to × 1.21 on trips of an hour or more (DfT 2025 average delay on local 'A' roads and motorways)." }, "depot": { "address": "Canning Town, London E16 1DQ", "lat": 51.5181741, "lng": 0.0134976, "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "at the centre of E16 1EW" } }, "options": { "drivers": 1, "returnToDepot": true, "shiftHours": 8, "serviceMinutes": 10 }, "estimated": false, "drivers": [ { "driver": 1, "stops": [ { "n": 1, "id": "0", "record_key": "rk1_ab3e99364e6ccdf1b263", "address": "Stratford Station, London E15 1AZ", "lat": 51.5418028, "lng": -0.0025686, "arrive_minutes": 12, "confidence": { "level": "high", "score": 0.95, "basis": "exact_building" } }, { "n": 2, "id": "4", "record_key": "rk1_79d1fef46539228c1969", "address": "Leyton High Road, London E10 5NA", "lat": 51.5608896, "lng": -0.0098956, "arrive_minutes": 29, "confidence": { "level": "medium", "score": 0.7, "basis": "named_place" } }, { "n": 3, "id": "1", "record_key": "rk1_6d6e0e9df6e5d864f97f", "address": "Hackney Central, London E8 1LL", "lat": 51.5470605, "lng": -0.0568749, "arrive_minutes": 52, "confidence": { "level": "medium", "score": 0.7, "basis": "named_place" } }, "… 2 more" ], "drive_minutes": 61, "work_minutes": 111, "miles": 14.2, "google_maps_links": [ { "label": "Stops 1–5, then back to the depot", "url": "https://www.google.com/maps/dir/Canning%20Town%2C%20London%20E16%201DQ/Stratford%20Station%2C%20London%20E15%201AZ/Leyton%20High%20Road%2C%20London%20E10%205NA/Hackney%20Central%2C%20London%20E8%201LL/Bethnal%20Green%20Road%2C%20London%20E2%206AH/Bow%20Road%2C%20London%20E3%204DH/Canning%20Town%2C%20London%20E16%201DQ" } ], "google_maps_link_all_stops": "https://www.google.com/maps/dir/Canning%20Town%2C%20London%20E16%201DQ/Stratford%20Station%2C%20London%20E15%201AZ/Leyton%20High%20Road%2C%20London%20E10%205NA/Hackney%20Central%2C%20London%20E8%201LL/Bethnal%20Green%20Road%2C%20London%20E2%206AH/Bow%20Road%2C%20London%20E3%204DH/Canning%20Town%2C%20London%20E16%201DQ" } ], "unassigned": [], "run": { "tool": "plan_routes", "at": "2026-10-13T15:59:26.020Z", "rows": 5, "routed": 5, "unassigned": 0, "sources": [ { "name": "InstaMaps roads: OpenStreetMap routed with Valhalla (GB and US)", "as_of": "2026-10-08" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "road drive times, normal traffic", "run_id": "run_184817a78044ee43", "confidence": { "high": 1, "medium": 4, "low": 0 } } } ``` ## get_travel_time_area: Area reachable within a travel time The area reachable from a place within N minutes by car, on foot or by bike, and which of your records fall inside each band. Docs: https://get-instamaps.com/mcp-server/tools/get_travel_time_area Use when: - "Customers within a 30-minute drive" - Service areas and catchments - Comparing what two sites can reach Not for: - A fixed-distance circle: filter_by_location or find_postcodes_in_radius Coverage: Great Britain and the US on our roads, with measured weekday traffic for driving. Sources: - InstaMaps roads: OpenStreetMap routed with Valhalla (GB and US) (2026-10-08) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: travel time on roads Inputs: - origin (object, required): An address or {lat, lng}. - minutes (array, default [30], up to 3): - mode (string, default "drive", one of drive | walk | cycle): - records (array, up to 500): {id, address} or {id, lat, lng}. Send your own ids to merge results back. - addresses (array, up to 500): Or plain addresses/postcodes, numbered from 1. - include_geometry (boolean, default false): - render (boolean, default false): Also keep the map (the bands, the origin and the records): a link, GeoJSON and KML. - title (string): The kept map's title when render is on. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 150 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - traffic (string, default "weekday", one of weekday | free_flow): weekday (default): road times with the area's measured weekday slowdown (DfT delay on local 'A' roads by council and on motorways in Great Britain; the Urban Mobility Report's Travel Time Index by US urban area). free_flow: empty roads. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: The area you can reach from one place within 5 to 60 minutes (up to three bands) driving, walking or cycling, with its size; and, given records (up to 500 with lat/lng, or 200 addresses), which band each record falls in: "which customers are within 30 minutes' drive of the depot". Our own routing on Great Britain and US roads; elsewhere an open routing service. Set include_geometry to get the GeoJSON polygons (larger answer). The bands show on a map in the chat by itself. Set render to true only when the user wants to keep or share the map: it returns a link, GeoJSON and KML, and update_map can change it later. Example request: ```json { "origin": "Leeds LS1 4AP", "minutes": [ 15, 30 ], "addresses": [ "York YO1 7HH", "Harrogate HG1 1HN" ] } ``` Answer headline: drive from Leeds LS1 4AP: 15 min 155 km² (0 records inside), 30 min 1023 km² (0 records inside) · 0 of 2 high confidence (2 medium, 0 low). Caveats: street or named place (1 row); postcode centre (1 row). Answer (trimmed): ```json { "confidence": { "summary": "0 of 2 high confidence (2 medium, 0 low). Caveats: street or named place (1 row); postcode centre (1 row).", "levels": { "high": 0, "medium": 2, "low": 0 }, "caveats": [ { "basis": "named_place", "level": "medium", "rows": 1, "ids": [ "1" ], "meaning": "Placed on a street or a named place; no house number was given, so it is not a doorstep point.", "next": "Fine for area questions. For doorstep precision, send a house number or coordinates." }, { "basis": "postcode_centre", "level": "medium", "rows": 1, "ids": [ "2" ], "meaning": "The street address was not matched, so the row sits at its postcode centre, usually within 100-300 m of the real spot.", "next": "Fine for nearest-place questions and distances over a kilometre; check it before relying on street-level detail." } ] }, "origin": { "input": "Leeds LS1 4AP", "lat": 53.795472, "lng": -1.555729, "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "at the centre of LS1 4AP" }, "note": "Every band is drawn from this point. The street address was not matched, so the row sits at its postcode centre, usually within 100-300 m of the real spot. Fine for nearest-place questions and distances over a kilometre; check it before relying on street-level detail." }, "mode": "drive", "engine": "our roads", "traffic": { "model": "weekday", "area": "Leeds (local A roads)", "factor_short_trips": 1.412, "factor_hour_plus": 1.205, "note": "Weekday estimate: free-flow road times × 1.41 for short trips in Leeds (local A roads), easing to × 1.21 on trips of an hour or more (DfT 2025 average delay on local 'A' roads and motorways).", "free_flow_minutes_drawn": [ 10.6, 21.7 ] }, "rings": [ { "minutes": 15, "area_km2": 155, "records_inside": 0 }, { "minutes": 30, "area_km2": 1023, "records_inside": 0 } ], "summary": { "records": 2, "placed": 2, "inside_largest": 0 }, "records": [ { "id": "1", "record_key": "rk1_d1ee5931d1454ef356c3", "input": "York YO1 7HH", "placed": true, "within_minutes": null, "lat": 53.96236, "lng": -1.08208, "confidence": { "level": "medium", "score": 0.7, "basis": "named_place" } }, { "id": "2", "record_key": "rk1_0e7eb0a93b4f9efb7566", "input": "Harrogate HG1 1HN", "placed": true, "within_minutes": null, "lat": 53.98829, "lng": -1.53779, "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "at the centre of HG1 1HN" } } ], "run": { "tool": "get_travel_time_area", "at": "2026-10-13T15:59:31.172Z", "rows": 2, "placed": 2, "not_placed": 0, "sources": [ { "name": "InstaMaps roads: OpenStreetMap routed with Valhalla (GB and US)", "as_of": "2026-10-08" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "travel time on roads", "run_id": "run_2593691b6bc89263", "confidence": { "high": 0, "medium": 2, "low": 0 } } } ``` ## get_location_facts: Official areas and zones for each address The official areas each address falls in: US census tract, income level, county, metro, HUBZone, Opportunity Zone, USDA eligibility, FEMA flood zone; GB conservation area, listed buildings, nearest UPRN, England flood zone. Docs: https://get-instamaps.com/mcp-server/tools/get_location_facts Use when: - Eligibility checks (HUBZone, Opportunity Zone, USDA, LMI tracts) - Planning constraints in Great Britain - Flood zone for a list of properties Not for: - Crime or natural-hazard ratings: get_area_risk - Warnings in force right now: get_live_hazards Coverage: US and Great Britain (England for flood zones). Measured: - Flood zones were checked against the issuers: FEMA flood zones matched FEMA's own lookup on 138 of 140 test addresses; England's flood zones matched the Environment Agency's API on 70 of 70 (October 2026). Sources: - US: Census tracts, FFIEC income levels, SBA HUBZones, Opportunity Zones, USDA RD eligibility, FEMA flood maps (2026-10-07) - GB: conservation areas and listed buildings (planning.data.gov.uk), OS Open UPRN, Environment Agency flood zones (July 2026) (2026-10-07) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Inputs: - records (array, up to 200): {id, address} or {id, lat, lng}. Send your own ids to merge results back. - addresses (array, up to 200): Or plain addresses/postcodes, numbered from 1. - fields (array): Only these facts (default: all that apply). flood is FEMA in the US, the Environment Agency in England. - region (string, one of us | uk): Optional; worked out per address from its postcode or ZIP. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 150 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: For up to 200 addresses or points, the official areas each one falls in, from our own copies of the official maps. Name the fields you need to keep the answer short. US: census tract (GEOID) and FFIEC income level (LMI), county, metro area, SBA HUBZone, Opportunity Zone, USDA Rural Development eligibility, FEMA flood zone (high-risk SFHA, base flood elevation). Great Britain: conservation area, listed buildings within 60 m, the nearest UPRN, and England's Environment Agency flood zone (1, 2 or 3). Each record says how it was placed; addresses we cannot place are listed with the reason. A guide, not an official determination. Example request: ```json { "addresses": [ "10 Downing Street, London SW1A 2AA", "1600 Pennsylvania Ave NW, Washington DC 20500" ] } ``` Answer headline: 2 of 2 placed and checked Answer (trimmed): ```json { "confidence": { "summary": "All 2 high confidence.", "levels": { "high": 2, "medium": 0, "low": 0 } }, "summary": { "records": 2, "placed": 2, "not_placed": 0 }, "records": [ { "id": "1", "record_key": "rk1_e9ec1ea25045e3a5e393", "ok": true, "lat": 51.50349, "lng": -0.1277, "matched": "10 Downing Street, London, England, SW1A 2AA, United Kingdom", "placed_by": "rooftop", "facts": { "conservation_area": "Whitehall", "listed_buildings_60m": 5, "nearest_listed": "11, DOWNING STREET SW1 (grade I, 14 m, list entry 1356989)", "uprn": "100023336956", "flood": { "zone": 3, "from": [ "the sea" ], "flooded_before": false } }, "confidence": { "level": "high", "score": 0.85, "basis": "geocode_checked", "why": "osm-house" } }, { "id": "2", "record_key": "rk1_0579e7bc70379e42dce9", "ok": true, "lat": 38.89767, "lng": -77.03655, "matched": "1600 Pennsylvania Avenue Northwest Washington DC 20500", "placed_by": "rooftop", "facts": { "tract": "11001980000", "county": "District of Columbia", "metro": "Washington-Arlington-Alexandria, DC-VA-MD-WV (Washington, DC-MD)", "income": { "year": 2026, "level": null, "lmi": null, "tract_mfi_pct": null, "note": "FFIEC publishes no income level for this tract (no median family income reported)." }, "hubzone": { "eligible": false, "basis": [] }, "opportunity_zone": false, "usda_eligible": false, "flood": { "zone": "X (outside the SFHA)", "high_risk": false } }, "confidence": { "level": "high", "score": 0.95, "basis": "geocode_checked", "why": "point" } } ], "run": { "tool": "get_location_facts", "at": "2026-10-13T15:59:32.186Z", "rows": 2, "placed": 2, "not_placed": 0, "sources": [ { "name": "US: Census tracts, FFIEC income levels, SBA HUBZones, Opportunity Zones, USDA RD eligibility, FEMA flood maps", "as_of": "2026-10-07" }, { "name": "GB: conservation areas and listed buildings (planning.data.gov.uk), OS Open UPRN, Environment Agency flood zones (July 2026)", "as_of": "2026-10-07" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "run_id": "run_837b23ecb370a878", "confidence": { "high": 2, "medium": 0, "low": 0 } } } ``` ## get_area_risk: Crime, flood or natural-hazard risk for each place One risk fact per place: recorded crime nearby (England and Wales) with the commonest types, flood zone (England, US), or FEMA natural-hazard rating (US). Docs: https://get-instamaps.com/mcp-server/tools/get_area_risk Use when: - Underwriting or site screening - "How much vehicle crime is around each of our depots?" - Comparing locations on one risk Not for: - Warnings in force right now: get_live_hazards / check_live_hazards - Zone eligibility: get_location_facts Coverage: Crime: England and Wales (police.uk, latest month). Flood: England and US. Hazard: US counties. Measured: - Flood answers come from the same checked flood maps as get_location_facts (138/140 vs FEMA, 70/70 vs the Environment Agency). Sources: - police.uk street-level crime (England and Wales) (the month in the answer) - Environment Agency Flood Map for Planning: flood zones (England, July 2026) (2026-10-07) - FEMA National Flood Hazard Layer: flood zones (US) (2026-10-07) - FEMA National Risk Index (2026-10-07) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Inputs: - metric (string, required, one of crime | flood | hazard): - kind (string): - records (array, up to 250): {id, address} or {id, lat, lng}. Send your own ids to merge results back. - addresses (array, up to 250): Or plain addresses/postcodes, numbered from 1. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 200 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: One risk fact for each of up to 250 addresses or points. crime: recorded crimes within about 250 m in the latest month (police.uk; England and Wales; kind narrows it: vehicle, burglary, violent, theft, shoplifting, robbery, anti-social, drugs, criminal damage, bike). flood: the flood zone with high/medium/low (Environment Agency for England, FEMA for the US). hazard: FEMA National Risk Index rating for the county (US; kind: overall, flood, hurricane, wildfire, tornado, earthquake, heat…). Rows outside a source's coverage say so rather than guess. Example request: ```json { "metric": "flood", "addresses": [ "York YO1 7HH", "10 Downing Street, London SW1A 2AA" ] } ``` Answer headline: flood zone: 2 of 2 answered · 1 of 2 high confidence (1 medium, 0 low). Caveats: street or named place (1 row). Answer (trimmed): ```json { "confidence": { "summary": "1 of 2 high confidence (1 medium, 0 low). Caveats: street or named place (1 row).", "levels": { "high": 1, "medium": 1, "low": 0 }, "caveats": [ { "basis": "named_place", "level": "medium", "rows": 1, "ids": [ "1" ], "meaning": "Placed on a street or a named place; no house number was given, so it is not a doorstep point.", "next": "Fine for area questions. For doorstep precision, send a house number or coordinates." } ] }, "metric": "flood", "label": "flood zone", "summary": { "records": 2, "placed": 2, "answered": 2 }, "records": [ { "id": "1", "record_key": "rk1_d1ee5931d1454ef356c3", "ok": true, "value": "Zone 1", "risk": "low", "source": "EA", "confidence": { "level": "medium", "score": 0.7, "basis": "named_place" } }, { "id": "2", "record_key": "rk1_e9ec1ea25045e3a5e393", "ok": true, "value": "Zone 3", "risk": "high", "source": "EA", "confidence": { "level": "high", "score": 0.95, "basis": "exact_building" } } ], "run": { "tool": "get_area_risk", "at": "2026-10-13T15:59:33.038Z", "rows": 2, "placed": 2, "not_placed": 0, "answered": 2, "sources": [ { "name": "Environment Agency Flood Map for Planning: flood zones (England, July 2026)", "as_of": "2026-10-07" }, { "name": "FEMA National Flood Hazard Layer: flood zones (US)", "as_of": "2026-10-07" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "run_id": "run_415808917ab6f692", "confidence": { "high": 1, "medium": 1, "low": 0 } } } ``` ## find_postcodes_in_radius: Every ZIP code or postcode within a radius Every US ZIP code, or UK postcode sector or district, within a radius of a place, nearest first. Docs: https://get-instamaps.com/mcp-server/tools/find_postcodes_in_radius Use when: - Service areas, delivery zones and direct-mail lists - "Which ZIP codes are within 25 miles of 10001?" - Ad targeting by postcode Not for: - Which of YOUR records are within a radius: filter_by_location Coverage: US (Census ZIP code areas) and the UK (postcode sectors and districts). Sources: - US Census 2024 ZCTA gazetteer: ZIP code centres (2024) - UK postcode district and sector centres (ONS-derived open postcode data) (2026-08-01) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: straight-line distance between centres Inputs: - center (string, required): A ZIP ("10001"), a UK postcode, sector or district ("SW1A 1AA", "SW1A 1", "SW1A"), an address, or "lat,lng". - radius (number, required): Up to 500 miles or 800 km. - unit (string, default "mi", one of mi | km): - granularity (string, default "sector", one of sector | district): UK only: postcode sectors ("SW1A 1") or districts ("SW1A"). - country (string, one of us | gb): Optional: worked out from the centre. - limit (number, default 500): Most areas to list, nearest first (up to 2,500); the total found is always given. - render (boolean): - title (string): Full description as served: Every US ZIP code, or every UK postcode sector (or district), whose centre is within a radius of a place, nearest first with the distance. The centre can be a ZIP, a UK postcode, sector or district, an address, or "lat,lng". For service areas, delivery zones, direct-mail and ad targeting lists. Straight-line distance between centres (an area counts when its centre is inside). Free: our own copy of the Census ZIP centres and the UK postcode centres. The answer has a run_id: write it into a sheet or map it (render_map from_run). For "who on MY list is within X miles", use filter_by_location instead. Set render to true only when the user wants to keep or share the map: it returns a link, GeoJSON and KML, and update_map can change it later. Example request: ```json { "center": "10001", "radius": 1, "limit": 5 } ``` Answer headline: 9 ZIP codes within 1 mi of 10001 (nearest 5 listed; raise limit for more) Answer (trimmed): ```json { "center": { "input": "10001", "label": "10001", "lat": 40.7506, "lng": -73.9973, "country": "US", "confidence": { "level": "high", "score": 0.9, "basis": "postcode_as_given", "why": "the centre of 10001" } }, "radius": 1, "unit": "mi", "kind": "ZIP code", "summary": { "found": 9, "records": 5, "more": 4 }, "records": [ { "id": "10001", "postcode": "10001", "distance_mi": 0, "lat": 40.7506, "lng": -73.9973 }, { "id": "10199", "postcode": "10199", "distance_mi": 0.1, "lat": 40.7514, "lng": -73.9972 }, { "id": "10119", "postcode": "10119", "distance_mi": 0.2, "lat": 40.7506, "lng": -73.9927 }, "… 2 more" ], "basis": "straight-line distance from the centre to each ZIP code's centre; an area counts when its centre is inside the circle", "sources": [ { "name": "US Census 2024 ZCTA gazetteer: ZIP code centres", "as_of": "2024" } ], "run": { "tool": "find_postcodes_in_radius", "at": "2026-10-13T15:59:33.713Z", "rows": 5, "sources": [ { "name": "US Census 2024 ZCTA gazetteer: ZIP code centres", "as_of": "2024" } ], "basis": "straight-line distance between centres", "run_id": "run_837d6de48cb8e6b6" } } ``` ## get_live_hazards: Flood, storm and earthquake warnings in force now Warnings and events in force now: England's flood warnings, US weather warnings, and worldwide earthquake shaking, hurricanes, floods, wildfires and volcanoes, with kind, level, area, times and outline. Docs: https://get-instamaps.com/mcp-server/tools/get_live_hazards Use when: - "Are there any flood warnings in force?" - "Where did the earthquake shake hardest?" - Tracking a hurricane's winds and cone - Event response before checking a portfolio Not for: - Which of your places are affected: check_live_hazards - Long-term flood zones: get_location_facts Usual chain: get_live_hazards → check_live_hazards → render_map with a live_hazards layer Coverage: England (Environment Agency), the US (National Weather Service), and worldwide: earthquakes M4.5+ of the past week with a ShakeMap (USGS), Atlantic and Pacific storms (National Hurricane Center), and GDACS floods, wildfires, volcanoes and other cyclones (automatic estimates). Refreshed every 10 minutes. Sources: - Environment Agency flood warnings (England), Open Government Licence (live, refreshed every 10 minutes) - US National Weather Service active alerts (live, refreshed every 10 minutes) - USGS earthquakes and ShakeMap shaking footprints (public domain) (live, refreshed every 10 minutes) - US National Hurricane Center active storms: winds, forecast cones, wind swaths (public domain) (live, refreshed every 10 minutes) - GDACS (UN and European Commission) disaster alerts: automatic estimates (live, refreshed every 10 minutes) Basis: the issuers' own warning, forecast and footprint areas Inputs: - region (string, default "all", one of gb | us | world | all): gb: England's flood warnings and world events touching Great Britain; us: National Weather Service warnings and world events touching the US; world: the earthquake, hurricane and GDACS feeds only; all: everything. - perils (array): Only these perils (default: all). - min_level (string, one of severe | warning | watch | advisory): Only this level and above (default: all). - render (boolean): - title (string): Full description as served: The warnings and events in force right now, refreshed every 10 minutes: England's flood warnings and alerts (Environment Agency); the US National Weather Service's warnings an insurer watches (tornado, severe thunderstorm, flood and flash flood, coastal flood and storm surge, hurricane and tropical storm, high wind, winter storm, fire weather); and worldwide: earthquakes of the past week with the area of each shaking level (USGS ShakeMap, intensity V to VIII+), active Atlantic and Pacific storms (National Hurricane Center: winds now at 34, 50 and 64 knots, the 5-day forecast cone, and where the winds have already been), and GDACS's floods, wildfires, volcanoes and the cyclones elsewhere (automatic estimates, rated a step lower). Each with its kind (warning: in force now; forecast: where it may go; footprint: where it has already hit, the claims view), level (severe, warning, watch, advisory), area, times and source link; the map shows their outlines. Which of the user's own places are affected: check_live_hazards. A map to keep with them: render_map with a live_hazards layer (beside the user's own layers). Set render to true only when the user wants to keep or share the map: it returns a link, GeoJSON and KML, and update_map can change it later. Example request: ```json { "region": "us", "min_level": "warning" } ``` Answer headline: 7 warnings in force (7 warning): 7 flood Answer (trimmed): ```json { "fetched_at": { "us": "2026-10-13T15:50:21.269Z" }, "summary": { "in_force": 7, "by_level": { "warning": 7 }, "by_peril": { "flood": 7 }, "by_region": { "us": 7 } }, "hazards": [ { "id": "nws-781b614c975339bd9c49", "region": "us", "peril": "flood", "level": "warning", "label": "Flood Warning", "area": "Brantley, GA", "issued": "2026-10-13T09:44:00-04:00", "expires": "2026-10-14T09:45:00-04:00", "message": "Flood Warning issued October 13 at 9:44AM EDT by NWS Jacksonville FL", "link": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.7414d44ef8a33988ac09b31b44c38b584c49a611.001.1", "center": { "lat": 31.2375, "lng": -81.8717 } }, { "id": "nws-3ed54624bd99493275ba", "region": "us", "peril": "flood", "level": "warning", "label": "Flood Warning", "area": "Calcasieu, LA", "issued": "2026-10-12T21:21:00-05:00", "expires": "2026-10-15T13:00:00-05:00", "message": "Flood Warning issued October 12 at 9:21PM CDT until October 15 at 1:00PM CDT by NWS Lake Charles LA", "link": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.8c39b0a475d4541f891e248563cc28d2eb7d8526.002.1", "center": { "lat": 30.3135, "lng": -93.1501 } }, { "id": "nws-9ed128f9f47fbbc7adbc", "region": "us", "peril": "flood", "level": "warning", "label": "Flood Warning", "area": "Calhoun, SC; Lexington, SC; Richland, SC", "issued": "2026-10-13T11:08:00-04:00", "expires": "2026-10-15T09:53:00-04:00", "message": "Flood Warning issued October 13 at 11:08AM EDT until October 15 at 9:53AM EDT by NWS Columbia SC", "link": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.9bbe987a3f2bc9745311d5a224438adc80fc59de.002.1", "center": { "lat": 33.875, "lng": -80.9727 } }, "… 4 more" ], "sources": [ { "name": "US National Weather Service active alerts", "as_of": "2026-10-13T15:50:21.269Z" } ], "run": { "tool": "get_live_hazards", "at": "2026-10-13T15:59:34.592Z", "sources": [ { "name": "US National Weather Service active alerts", "as_of": "2026-10-13T15:50:21.269Z" } ], "basis": "the issuers' own warning areas" } } ``` ## check_live_hazards: Which of your places are inside a live warning or event Which of your places are inside or near a warning or event now (or were hit by one), with insured values added up. Docs: https://get-instamaps.com/mcp-server/tools/check_live_hazards Use when: - Insurers and brokers checking a book during an event - "Which of our properties felt strong shaking?" - Claims triage after a storm or earthquake - "Which properties are in a flood warning right now?" Not for: - Long-term risk: get_area_risk, get_location_facts Coverage: Everything get_live_hazards covers: England and US warnings, and worldwide earthquakes, hurricanes and GDACS events. Refreshed every 10 minutes. Sources: - Environment Agency flood warnings (England), Open Government Licence (live, refreshed every 10 minutes) - US National Weather Service active alerts (live, refreshed every 10 minutes) - USGS earthquakes and ShakeMap shaking footprints (public domain) (live, refreshed every 10 minutes) - US National Hurricane Center active storms: winds, forecast cones, wind swaths (public domain) (live, refreshed every 10 minutes) - GDACS (UN and European Commission) disaster alerts: automatic estimates (live, refreshed every 10 minutes) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: inside the issuer's area, or straight-line distance to its edge Inputs: - records (array, up to 500): {id, address} or {id, lat, lng}. Send your own ids to merge results back. - addresses (array, up to 500): Or plain addresses/postcodes, numbered from 1. - near_km (number, default 5): Also flag places within this distance of a warning (0 to 50 km). - value_field (string): The records' field to add up (e.g. "TIV"); found automatically when it is called TIV, sum insured, insured value or value. - region (string, default "all", one of gb | us | all): - perils (array): - min_level (string, one of severe | warning | watch | advisory): - render (boolean): - title (string): - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 500 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: Up to 500 addresses or points (more by reference: source, run as a background job) against the warnings in force now (get_live_hazards). Each record: inside a warning, near one (within near_km, default 5), clear, or unplaced with the reason; with the warnings that touch it (one per event: an earthquake's strongest shaking there, a storm's strongest winds), their kind, level, area and end time. Footprints (shaking, a storm's past winds, a flood's extent) show which places were hit: the claims view. A value column (TIV, sum insured, insured value, value; or name it in value_field) is added up for the places inside and near. On the map, places inside a warning pulse red over the pulsing warning outlines. Warning areas are the issuers' own; a place near an edge is worth a look either way. Set render to true only when the user wants to keep or share the map: it returns a link, GeoJSON and KML, and update_map can change it later. Example request: ```json { "records": [ { "id": "leeds", "address": "Leeds LS1 4AP", "TIV": 2500000 }, { "id": "austin", "address": "500 Congress Avenue, Austin, TX 78701", "TIV": 900000 } ] } ``` Answer headline: 0 of 2 places inside a live warning, 0 within 5 km of one, 2 clear · value inside 0, near 0 (28 warnings in force) · 1 of 2 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row). Answer (trimmed): ```json { "confidence": { "summary": "1 of 2 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row).", "levels": { "high": 1, "medium": 1, "low": 0 }, "caveats": [ { "basis": "postcode_centre", "level": "medium", "rows": 1, "ids": [ "leeds" ], "meaning": "The street address was not matched, so the row sits at its postcode centre, usually within 100-300 m of the real spot.", "next": "Fine for nearest-place questions and distances over a kilometre; check it before relying on street-level detail." } ] }, "fetched_at": { "gb": "2026-10-13T15:50:21.269Z", "us": "2026-10-13T15:50:21.269Z" }, "near_km": 5, "summary": { "records": 2, "placed": 2, "inside": 0, "near": 0, "clear": 2, "unplaced": 0, "warnings_in_force": 28, "warnings_touching": 0, "by_peril": {}, "value_inside": 0, "value_near": 0, "rows_with_value": 2 }, "records": [ { "id": "leeds", "record_key": "rk1_5fac800fc81c4adfc5dc", "input": "Leeds LS1 4AP", "status": "clear", "value": 2500000, "lat": 53.79547, "lng": -1.55573, "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "at the centre of LS1 4AP" } }, { "id": "austin", "record_key": "rk1_c7b9628c539ecd3671c6", "input": "500 Congress Avenue, Austin, TX 78701", "status": "clear", "value": 900000, "lat": 30.26748, "lng": -97.74362, "confidence": { "level": "high", "score": 0.95, "basis": "exact_building" } } ], "sources": [ { "name": "Environment Agency flood warnings (England), Open Government Licence", "as_of": "2026-10-13T15:50:21.269Z" }, { "name": "US National Weather Service active alerts", "as_of": "2026-10-13T15:50:21.269Z" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "run": { "tool": "check_live_hazards", "at": "2026-10-13T15:59:35.746Z", "rows": 2, "placed": 2, "not_placed": 0, "sources": [ { "name": "Environment Agency flood warnings (England), Open Government Licence", "as_of": "2026-10-13T15:50:21.269Z" }, { "name": "US National Weather Service active alerts", "as_of": "2026-10-13T15:50:21.269Z" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "inside the issuer's warning area, or straight-line distance to its edge", "run_id": "run_abd5d501d50221d9", "confidence": { "high": 1, "medium": 1, "low": 0 } } } ``` ## find_nearby: Places of a kind near each address The nearest, the count, or a list of places of a kind (stations, schools, supermarkets, pharmacies…) around each address. Docs: https://get-instamaps.com/mcp-server/tools/find_nearby Use when: - "Nearest station to each property" - Counting competitors or amenities around sites - Site selection Not for: - Official records with ratings (CQC, NHS, food hygiene): find_official_places Coverage: UK and US, from OpenStreetMap; each answer says how well that kind of place is mapped. Sources: - OpenStreetMap places, InstaMaps index (UK and US) (2026-10-08) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: straight-line distance Inputs: - category (string, required): - mode (string, default "nearest", one of nearest | count | list): - radius_km (number): Default 10 km for nearest, 2 km otherwise. - n (integer): How many places to return per record. - records (array, up to 500): {id, address} or {id, lat, lng}. Send your own ids to merge results back. - addresses (array, up to 500): Or plain addresses/postcodes, numbered from 1. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 150 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: For up to 500 addresses or points in the UK and the US: the nearest places of a kind (mode nearest), how many are within a radius (count), or a list (list). One answer carries up to 300 places (records × n); count mode has no such limit. Categories: pharmacy, station, supermarket, school, GP, hospital, pub, cafe, restaurant, car park, EV charger, bus stop, bank, post office, gym, park and more (an unknown word gets the full list back). From open map data on our own index: classic amenities are well covered, trades patchily. For A&E, hospitals, GP practices, care homes, dentists and NHS pharmacies in England, find_official_places answers from the CQC and NHS registers, with ratings: open map data mixes these up. Example request: ```json { "category": "pharmacy", "addresses": [ "Leeds LS1 4AP" ], "n": 3 } ``` Answer headline: Pharmacy (nearest, 10 km): 1 of 1 placed · 0 of 1 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row); open map data, not the official register (1 row). Answer (trimmed): ```json { "confidence": { "summary": "0 of 1 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row); open map data, not the official register (1 row).", "levels": { "high": 0, "medium": 1, "low": 0 }, "caveats": [ { "basis": "postcode_centre", "level": "medium", "rows": 1, "ids": [ "1" ], "meaning": "The street address was not matched, so the row sits at its postcode centre, usually within 100-300 m of the real spot.", "next": "Fine for nearest-place questions and distances over a kilometre; check it before relying on street-level detail." }, { "basis": "official_register_exists", "level": "medium", "rows": 1, "ids": [ "1" ], "meaning": "From open map data, where a \"hospital\" can be a clinic or a mental-health unit; an official register has the authoritative answer.", "next": "Use find_official_places for A&E, GP practices, care homes, dentists and pharmacies." } ] }, "category": { "key": "pharmacy", "label": "Pharmacy" }, "mode": "nearest", "radius_km": 10, "coverage": "good", "summary": { "records": 1, "placed": 1, "unplaced": 0, "outside": 0, "offline": 0 }, "records": [ { "id": "1", "record_key": "rk1_5fac800fc81c4adfc5dc", "ok": true, "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "at the centre of LS1 4AP", "also": [ "official_register_exists" ] }, "places": [ { "name": "Boots", "km": 0.52, "address": "Unit 15 New Station Street, Leeds, LS1 4DT", "postcode": "LS1 4DT", "lat": 53.79507, "lng": -1.54778 }, { "name": "Living Care Deliveries Leeds", "km": 0.6, "address": "David Street, Leeds, LS11 5JJ", "postcode": "LS11 5JJ", "lat": 53.79055, "lng": -1.55189 }, { "name": "Boots", "km": 0.67, "address": "27 Albion Street, Leeds, LS1 5AT", "postcode": "LS1 5AT", "lat": 53.79719, "lng": -1.54596 } ] } ], "run": { "tool": "find_nearby", "at": "2026-10-13T15:59:37.337Z", "rows": 1, "placed": 1, "not_placed": 0, "sources": [ { "name": "OpenStreetMap places, InstaMaps index (UK and US)", "as_of": "2026-10-08" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "straight-line distance", "run_id": "run_d572bc5f02b7e6e0", "confidence": { "high": 0, "medium": 1, "low": 0 } } } ``` ## find_official_places: Official registers near each address (UK) The official record: A&E departments, hospitals, GP practices, care homes and dentists with CQC ratings, NHS pharmacies, food hygiene ratings; or the record of the business at each row. Docs: https://get-instamaps.com/mcp-server/tools/find_official_places Use when: - "Nearest A&E to each site and who runs it" - Care home ratings near an address - The hygiene rating of each restaurant on a list Not for: - Shops, stations and other everyday places: find_nearby Coverage: England for CQC, England and Wales for NHS pharmacies, the UK for food hygiene. Sources: - Care Quality Commission register and latest ratings (England) (2026-10-07) - Food Standards Agency food hygiene ratings (UK) (live) - NHS Organisation Data Service: active pharmacies (England, Wales, Isle of Man) (2026-10-10) - InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08) Basis: straight-line distance Inputs: - kind (string, required, one of ae | hospital | urgent_care | gp | care_home | nursing_home | dentist | hospice | pharmacy | food): - mode (string, default "nearest", one of nearest | count | list | at): at: the registered place at each address itself (send name). - radius_km (number): How far to look. Defaults: A&E 60, hospital 30, GP 10, care home 10, pharmacy 5, food 1. - n (integer): How many places to return per record. - rating (array): CQC ratings to keep, e.g. ["Requires improvement", "Inadequate"]. For A&E, the rating of its urgent and emergency services. - nhs (boolean): Hospitals: true for NHS only, false for independent only. - include_specialist (boolean, default false): A&E: also the eye and children's hospitals' emergency departments (left out by default). - food_type (string): restaurant, takeaway, pub, supermarket, shop, hotel, school, caring, mobile or manufacturer. - min_hygiene (integer): - max_hygiene (integer): - records (array, up to 500): {id, address} or {id, lat, lng}. Send your own ids to merge results back. - addresses (array, up to 500): Or plain addresses/postcodes, numbered from 1. - background (boolean): With source: run as a background job and answer at once with job_id (automatic past 200 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. Full description as served: What open map data doesn't have, from the official registers. England (the Care Quality Commission's register, our copy, with each place's latest rating and date): A&E departments (NHS hospitals with a full emergency department: CQC rates their urgent and emergency services and critical care; with the A&E's rating and the NHS trust that runs it), urgent care (urgent treatment centres and minor injuries units, including hospitals whose A&E became one), hospitals (NHS or independent), GP practices, care homes, nursing homes, dentists, hospices; and NHS community pharmacies from the NHS's own register (England, Wales, Isle of Man; ODS code and UPRN, on their building where the register gives it). UK (the Food Standards Agency, live): food businesses with their hygiene rating. For up to 500 addresses or points (100 for food): the nearest (mode nearest), how many within a radius (count) or a list (list), straight-line km; or mode at: the registered place AT each address (send the business name as name), e.g. the hygiene rating of each restaurant on a customer list or the CQC rating of each care home, matched by name and postcode and saying how; a row that can't be matched says why and lists what is registered there. Filter by rating (Outstanding, Good, Requires improvement, Inadequate, not rated), NHS or independent, food type, hygiene score. Each place carries its register IDs (CQC location, NHS ODS code, UPRN, FSA FHRS), a link to its official page and its source; CQC covers England and the NHS pharmacy register England and Wales; addresses outside a register are told so. Use find_nearby for everything else (shops, stations, parks). Example request: ```json { "kind": "gp", "addresses": [ "Leeds LS1 4AP" ], "n": 2 } ``` Answer headline: GP practice (nearest, 10 km): 1 of 1 records have one · 0 of 1 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row). Answer (trimmed): ```json { "confidence": { "summary": "0 of 1 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row).", "levels": { "high": 0, "medium": 1, "low": 0 }, "caveats": [ { "basis": "postcode_centre", "level": "medium", "rows": 1, "ids": [ "1" ], "meaning": "The street address was not matched, so the row sits at its postcode centre, usually within 100-300 m of the real spot.", "next": "Fine for nearest-place questions and distances over a kilometre; check it before relying on street-level detail." } ] }, "kind": { "key": "gp", "label": "GP practice" }, "mode": "nearest", "radius_km": 10, "basis": "straight-line distance; CQC places sit at the centre of their postcode", "sources": [ { "name": "Care Quality Commission register and latest ratings (England): directory of 07 October 2026, ratings of 1 October 2026", "as_of": "2026-10-07" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "summary": { "records": 1, "placed": 1, "found": 1, "outside_coverage": 0 }, "records": [ { "id": "1", "record_key": "rk1_5fac800fc81c4adfc5dc", "ok": true, "at": [ 53.79547, -1.55573 ], "confidence": { "level": "medium", "score": 0.65, "basis": "postcode_centre", "why": "at the centre of LS1 4AP" }, "count": 70, "places": [ { "name": "The Light", "kind": "GP practice", "operator": "One Medicare Ltd", "rating": "Good", "rated": "2024-04-15", "km": 0.83, "address": "Balcony Level, The Light, The Headrow, Leeds", "postcode": "LS1 8TL", "lat": 53.80006, "lng": -1.54567, "ids": { "cqc": "1-583552332", "ods": "Y02002" }, "url": "https://www.cqc.org.uk/location/1-583552332", "source": "CQC" }, { "name": "Priory View Medical Centre", "kind": "GP practice", "operator": "Priory View Medical Centre", "rating": "Good", "rated": "2017-01-11", "km": 1.34, "address": "2a Green Lane, Leeds", "postcode": "LS12 1HU", "lat": 53.79165, "lng": -1.57515, "ids": { "cqc": "1-550196700", "ods": "B86024" }, "url": "https://www.cqc.org.uk/location/1-550196700", "source": "CQC" } ] } ], "run": { "tool": "find_official_places", "at": "2026-10-13T15:59:38.989Z", "rows": 1, "placed": 1, "not_placed": 0, "sources": [ { "name": "Care Quality Commission register and latest ratings (England): directory of 07 October 2026, ratings of 1 October 2026", "as_of": "2026-10-07" }, { "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io", "as_of": "2026-10-08" } ], "basis": "straight-line distance", "run_id": "run_6452809fb8f9e425", "confidence": { "high": 0, "medium": 1, "low": 0 } } } ``` ## render_map: Make a map to keep, share or change A hosted, layered map to keep or share: pins, lines or areas, colours by field, a legend, GeoJSON and KML. Docs: https://get-instamaps.com/mcp-server/tools/render_map Use when: - The user wants a link to keep, share or change later - Combining several answers on one map - A live-warnings layer beside the user's own places Not for: - Just seeing an answer: answers with places already show a map in the chat Usual chain: any data tool (from_run) → render_map → update_map Coverage: Worldwide. Inputs: - title (string): The map's title (and how to find it again). - layers (array, up to 20): One or more layers, drawn in order (later ones on top). - legend (boolean, default true): - rows (array, up to 2500): Shortcut for a one-layer map: rows with lat/lng or addresses. - color_by (string): With rows: the field to colour the pins by. - source (object): Instead of typing rows: { sheet: "", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "" }, or { run: "" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are. - from_run (string): A run_id from an earlier answer: its rows as the map's pins (with color_by, bins and labels), in one call. - bins (array): With from_run, source or rows and color_by on a number: band breaks. - labels (boolean): With from_run, source or rows: names on the map. Full description as served: Only when the user wants a map to keep, share or change later: answers with places already show a map in the chat. Makes a hosted map (a link anyone can open, plus GeoJSON and KML for GIS tools and Google Earth) from up to 20 layers in one call. Each layer is pins (rows with lat/lng, or addresses placed for you, up to 200 addresses a call), lines or areas; one colour, or a colour per value of a field (color_by); a number field colours light to dark, in the bands the user asked for when given (bins: [25000, 100000] = under 25k, 25k to under 100k, 100k and over); names on the map if wanted (labels); up to 2,500 pins a map. Returns map_id: change the map later with update_map (the link stays the same). Same title as an earlier map = that map replaced in place, same link, the old version kept. Example request: ```json { "title": "Docs example: two depots", "rows": [ { "id": "leeds", "name": "Leeds depot", "lat": 53.7966, "lng": -1.5484 }, { "id": "york", "name": "York depot", "lat": 53.958, "lng": -1.0803 } ] } ``` Answer headline: Made "Docs example: two depots": 1 layer(s), 2 pins: https://get-instamaps.com/v/9hd9pnytqs Answer (trimmed): ```json { "map_id": "9hd9pnytqs", "url": "https://get-instamaps.com/v/9hd9pnytqs", "geojson": "https://get-instamaps.com/v/9hd9pnytqs.geojson", "kml": "https://get-instamaps.com/v/9hd9pnytqs.kml", "version": 1, "created": true, "layers": [ { "name": "Rows", "points": 2, "lines": 0, "areas": 0 } ] } ``` ## update_map: Change a kept map Change a kept map in place: add or remove layers, move or add pins, recolour, rename; the link stays the same and earlier versions are kept. Docs: https://get-instamaps.com/mcp-server/tools/update_map Use when: - Correcting or extending a map made earlier - Recolouring by a different field Not for: - Making a new map: render_map Coverage: Worldwide. Inputs: - map (string, required): The map_id or link render_map returned. - title (string): A new title. - add_layers (array): - remove_layers (array): Names of layers to remove. - update_layers (array): - upsert_points (array): Move, rename or re-field a pin by its id, or add a new one (new pins need lat/lng or an address). - remove_points (array): - legend (boolean): - revert_to (integer): Put this earlier version back (it becomes the newest version; nothing is lost). Full description as served: Change a map made with render_map (or a tool's render): add or remove layers; move, rename or add pins (by id, with lat/lng or an address); remove pins; recolour a layer (one colour, or by a field's values, with colours per value if wanted, or by a number in the user's own bands: bins); show or hide names or a whole layer; rename the map. Several changes in one call. The link stays the same, and every earlier version is kept: revert_to puts one back. get_map lists the layers, pin ids and fields. Example request: ```json { "map": "9hd9pnytqs", "upsert_points": [ { "layer": "Rows", "id": "harrogate", "name": "Harrogate depot", "lat": 53.9921, "lng": -1.5418 } ] } ``` Answer headline: Updated "Docs example: two depots" to version 2: added harrogate to "Rows". Same link: https://get-instamaps.com/v/9hd9pnytqs Answer (trimmed): ```json { "map_id": "9hd9pnytqs", "url": "https://get-instamaps.com/v/9hd9pnytqs", "geojson": "https://get-instamaps.com/v/9hd9pnytqs.geojson", "kml": "https://get-instamaps.com/v/9hd9pnytqs.kml", "version": 2, "changes": [ "added harrogate to \"Rows\"" ], "layers": [ { "name": "Rows", "points": 3, "lines": 0, "areas": 0 } ] } ``` ## get_map: Look at a kept map Look at a kept map from an earlier conversation: its layers, pin ids and fields. With no map named, list the person's own maps, including the ones they made in the InstaMaps Google Sheets add-on. Docs: https://get-instamaps.com/mcp-server/tools/get_map Use when: - Before update_map, to see what is there - "Show me my maps" or "open my delivery map" - Opening a get-instamaps.com/map/... link from the Sheets add-on Coverage: Maps made with render_map or a tool's render, and the signed-in person's own Sheets add-on maps. Inputs: - map (string): The map_id or link. Leave out to list the person's maps. - layer (string): A layer whose pins to list ("pins" for a Sheets add-on map). Full description as served: A map made with render_map: its link and downloads, its layers with their pin ids and fields, its version and the earlier versions kept; with layer, that layer's pins in full (first 500). Shows the map in the chat. Use it before update_map on a map from an earlier conversation. Also opens maps the person made in the InstaMaps Google Sheets add-on (a get-instamaps.com/map/... link); layer "pins" lists their pins. With no map, lists the person's own maps: use that when they ask to see their maps or give no link. Example request: ```json { "map": "9hd9pnytqs" } ``` Answer headline: "Docs example: two depots" version 2: Rows (3 pins) Answer (trimmed): ```json { "map_id": "9hd9pnytqs", "url": "https://get-instamaps.com/v/9hd9pnytqs", "geojson": "https://get-instamaps.com/v/9hd9pnytqs.geojson", "kml": "https://get-instamaps.com/v/9hd9pnytqs.kml", "title": "Docs example: two depots", "version": 2, "layers": [ { "name": "Rows", "points": 3, "lines": 0, "areas": 0, "point_ids": [ "leeds", "york", "harrogate" ], "fields": [] } ], "earlier_versions": [ 1 ] } ``` ## combine_runs: Combine kept runs on the same places Join two to six kept runs on the place ID every tool returns (record_key) and say what changed between them. Docs: https://get-instamaps.com/mcp-server/tools/combine_runs Use when: - "Which sites' nearest A&E got further away since September?" - Merging geocode results with facts or risk for the same places Coverage: Any runs from earlier answers (run_ids) or tables you send. Inputs: - runs (array, required, up to 6): Oldest first. - key (string, default "record_key"): The place ID column every run has. - columns (array): Only these columns from each run (default: all). - compare (array): Columns to compare between runs: numbers get the change, text whether it changed. - only_changed (boolean, default false): Full description as served: Join two to 6 kept runs (run_ids from earlier answers, or tables such as dated tabs in Drive) on the place ID every tool returns (record_key), each run's columns kept separate under its name, and say what changed between the first and last run for the columns named in compare: "sites whose nearest A&E got further away since September". Places in only some runs are kept and say which; only_changed returns just the rows that changed. Up to 5,000 rows a run; the first 300 combined rows come back. Example request: ```json { "runs": [ "run_… (geocode_batch)", "run_… (get_area_risk flood)" ], "key": "record_key" } ``` Answer headline: 2 places across 2 runs, 2 in every run Answer (trimmed): ```json { "key": "record_key", "runs": [ "run run_07c597b8258f61ac (geocode_batch)", "run run_ec5e360aa4e6152c (get_area_risk)" ], "summary": { "places": 2, "in_every_run": 2 }, "rows": [ { "record_key": "rk1_e9ec1ea25045e3a5e393", "run run_07c597b8258f61ac (geocode_batch): id": "hq", "run run_07c597b8258f61ac (geocode_batch): address": "10 Downing Street, London SW1A 2AA", "run run_07c597b8258f61ac (geocode_batch): Placed": "placed", "run run_07c597b8258f61ac (geocode_batch): Precision": "rooftop", "run run_07c597b8258f61ac (geocode_batch): Confidence": "high", "run run_07c597b8258f61ac (geocode_batch): House number": "10", "run run_07c597b8258f61ac (geocode_batch): Street": "Downing Street", "run run_07c597b8258f61ac (geocode_batch): City": "London", "run run_07c597b8258f61ac (geocode_batch): County": "Greater London", "run run_07c597b8258f61ac (geocode_batch): State": "England", "run run_07c597b8258f61ac (geocode_batch): Postcode": "SW1A 2AA", "run run_07c597b8258f61ac (geocode_batch): Country": "GB", "run run_07c597b8258f61ac (geocode_batch): Council": "Westminster", "run run_07c597b8258f61ac (geocode_batch): UPRN": "100023336956", "run run_07c597b8258f61ac (geocode_batch): Record key": "rk1_e9ec1ea25045e3a5e393", "run run_ec5e360aa4e6152c (get_area_risk): id": "hq", "run run_ec5e360aa4e6152c (get_area_risk): address": "10 Downing Street, London SW1A 2AA", "run run_ec5e360aa4e6152c (get_area_risk): flood zone": "Zone 3", "run run_ec5e360aa4e6152c (get_area_risk): Confidence": "high", "in_runs": [ "run run_07c597b8258f61ac (geocode_batch)", "run run_ec5e360aa4e6152c (get_area_risk)" ] }, { "record_key": "rk1_fb67d1e967e22b14fe65", "run run_07c597b8258f61ac (geocode_batch): id": "york", "run run_07c597b8258f61ac (geocode_batch): address": "York Minster, York YO1 7HH", "run run_07c597b8258f61ac (geocode_batch): Placed": "placed", "run run_07c597b8258f61ac (geocode_batch): Precision": "rooftop", "run run_07c597b8258f61ac (geocode_batch): Confidence": "high", "run run_07c597b8258f61ac (geocode_batch): Street": "Minster Yard", "run run_07c597b8258f61ac (geocode_batch): City": "York", "run run_07c597b8258f61ac (geocode_batch): County": "York", "run run_07c597b8258f61ac (geocode_batch): State": "England", "run run_07c597b8258f61ac (geocode_batch): Postcode": "YO1 7HH", "run run_07c597b8258f61ac (geocode_batch): Country": "GB", "run run_07c597b8258f61ac (geocode_batch): Council": "York", "run run_07c597b8258f61ac (geocode_batch): UPRN": "200004778770", "run run_07c597b8258f61ac (geocode_batch): Record key": "rk1_fb67d1e967e22b14fe65", "run run_ec5e360aa4e6152c (get_area_risk): id": "york", "run run_ec5e360aa4e6152c (get_area_risk): address": "York Minster, York YO1 7HH", "run run_ec5e360aa4e6152c (get_area_risk): flood zone": "Zone 1", "run run_ec5e360aa4e6152c (get_area_risk): Confidence": "medium", "in_runs": [ "run run_07c597b8258f61ac (geocode_batch)", "run run_ec5e360aa4e6152c (get_area_risk)" ] } ] } ``` ## get_job: How far a background job has got How far a background job has got: status, rows done, minutes left, and its run_id when done. Docs: https://get-instamaps.com/mcp-server/tools/get_job Use when: - After any tool answers with a job_id (a list too big for one call) Coverage: Jobs started by the same person; checking costs no calls. Inputs: - job_id (string, required): Full description as served: For a job a tool started (a list by reference bigger than one call): its status (queued, running, done, failed), rows done of the total, about how many minutes are left, and when done its run_id (use it as source { run } in any tool, or from_run in render_map) and what was written to the sheet. ## write_to_sheet: Put an answer into a Google Sheet Put an earlier answer into a Google Sheet: new dated columns beside the rows it came from, or a new tab. Never overwrites a cell. The only tool that writes. Docs: https://get-instamaps.com/mcp-server/tools/write_to_sheet Use when: - The user wants the results in their sheet, next to their rows - A background job should fill the sheet as it goes (pass its job_id) - An answer should be kept as a dated tab of its own Not for: - A file to download or attach: geocode_batch with format "csv" - A map to share: render_map Usual chain: geocode_batch (or any tool) with source { sheet } → write_to_sheet with its run_id Coverage: Google Sheets shared with the InstaMaps service account as Editor; rows are matched by id, and a row that now holds a different place is skipped and named. Inputs: - run_id (string): The run_id from an answer (run.run_id), or from get_job when a job is done. - job_id (string): Or a background job's job_id. - sheet (string): A Google Sheets link. Default: the sheet the rows came from. - tab (string): The tab. Default: the tab the rows came from. - mode (string, one of beside | new_tab): beside: new columns next to the rows they came from (the default when the run came from this tab). new_tab: the rows as a table in a new tab (the default for any other sheet). - columns (array): Which of the answer's fields to write, by name (e.g. "Latitude", "Confidence", "Nearest A&E", or geocode keys such as postcode or uprn). Default: the tool's usual columns. Full description as served: Writes an earlier answer into a Google Sheet without overwriting anything. Give run_id (every answer has one) to write its rows as new dated columns beside the rows they came from (matched by id; a row that now holds a different place is skipped and named), or as a table in a new tab; give job_id (a background job) to write each chunk beside its rows as it finishes, or the whole run when it is done. Each write adds a line to an "InstaMaps runs" tab. The sheet must be shared with the InstaMaps service account as Editor; if it isn't, the error names the address. Example request: ```json { "run_id": "run_ae02fe5fb0d18808", "mode": "new_tab", "columns": [ "lat", "lng", "postcode", "council", "uprn", "confidence" ] } ``` Answer headline: Wrote 3 rows to "geocode_batch · 2026-10-13 17:36" (a new tab) in InstaMaps write_to_sheet test (landmarks), and a line in "InstaMaps runs". Answer (trimmed): ```json { "run_id": "run_ae02fe5fb0d18808", "sheet": "InstaMaps write_to_sheet test (landmarks)", "tab": "geocode_batch · 2026-10-13 17:36", "columns": [ "ID", "Name", "Address", "Latitude", "Longitude", "Postcode", "Council", "UPRN", "Confidence" ], "rows": 3, "run_log": "InstaMaps runs", "mode": "new_tab" } ```