OpenUrbe for agents
Official statistics for each of Barcelona’s 73 neighbourhoods (barris) and 10 districts, as tools an AI agent can call: rent and sale prices, income per person (net or gross), registered population, licensed tourist flats, and recorded offences. Read-only, no key, no account.
Every figure comes back with its source, dataset, period and caveats, so an answer built on it can be cited. Where a figure is published only by district and has been applied to the neighbourhoods inside it, the response says so.
The endpoint
https://openurbe.com/mcpStreamable HTTP, stateless. No authentication. A small per-minute budget applies per address; if you need more, get in touch and use the X-API-Key header.
The tools
- list_measures
- Every layer, its geo levels, periods, dimensions and caveats. Call it first.
- get_snapshot
- Rank territories for one layer at one period.
- get_trend
- Follow one or two layers over time, for up to five territories.
- get_composition
- Split one territory across a dimension's values.
- match_neighbourhoods
- Rank neighbourhoods against several weighted criteria at once.
- neighbourhood_profile
- Every layer's latest figure for one to three territories.
Every tool also takes an optional city; left out, Barcelona answers.
What comes back
Every operation answers in one shape (result_version 1), as structured content and, minified, as the text block. rows are flat records, each column described once in fields; measuresgives each layer’s label and unit (EUR/month, persons, count…), and rows that mix layers carry their own unit. Every territory row carries the publisher’s code. stats holds the computed comparisons — median, rank, percentile, change — so a model quotes them instead of working them out. sourcescarries each figure’s source, dataset, licence, period and caveats.
charts are Vega-Lite v5 specs that read the rows under the name rows; a map draws the GeoJSON at geometry.url, joined on code. Hosts that support MCP Apps render them in place. A refusal comes back as an error with error.code, error.message and, when something close exists, error.did_you_mean.
Without an MCP client
The same five operations are plain HTTP, with the same request bodies and the same responses. The OpenAPI description at /openapi.json is enough for a Custom GPT action or a Vertex tool.
curl -s https://barri-viu.fly.dev/api/v1/cities/barcelona/ops/catalogue
curl -s -X POST https://barri-viu.fly.dev/api/v1/cities/barcelona/ops/snapshot \
-H 'Content-Type: application/json' \
-d '{"layer":"housing/rent","order":"asc","top_n":10}'What it will not do
- It holds no data on transport, schools, hospitals, noise, green space or air quality, and no personal data of any kind. A question outside the catalogue is refused rather than approximated.
- It reports; it does not explain. No operation will attribute a cause to a change in any figure, and a period that coincided with a known event is reported as a coincidence in time.
- Counts are not rates. Recorded offences are absolute counts published by district, and busier districts record more partly because more people are there.
Licence and attribution
Figures are redistributed unmodified from Ajuntament de Barcelona’s Open Data BCN and Portaldades portals under CC BY 4.0. Cite Ajuntament de Barcelona as the publisher of the figures. The site is at openurbe.com, and /llms.txt describes the rest of it.