Skip to main content
Glama

Market facts for an area

market_facts
Read-onlyIdempotent
Price, price per sqm and turnover rate for ONE geography × asset class ×
bedroom band × period, from the pre-cubed area_facts table.

Metrics: sales_price, price_psm, turnover_rate are populated today.
rental_value, gross_yield and days_on_market are NOT — the pipeline has
never backfilled them, so they come back null and are named in the
response's `metrics_with_no_data`. Do not compare or rank on them, and do
not report a null from them as "no activity"; it means "not collected".

turnover_rate is sales as a share of the stock that could have sold. It
is the liquidity measure — transaction COUNT is market size, not
liquidity (W2 has the largest dwelling stock of any London district and
near-bottom turnover).

Geography is `postcode` (resolved to its district — the cube has no
sector or unit grain) or `lad_code` (a local-authority NAME, e.g.
"Lambeth", not a GSS code). There are no LSOA or ward areas in the
warehouse; those selectors return 422.

To compare AREAS against each other use `market_ranking`, not repeated
calls here. For "how many sales" use `market_volume_series` — the `tx_n`
here counts only UPRN-matched, non-anomalous sales and runs well short of
the registry. The prices are sound; the count is a sample size.

READ `tx_decision` BEFORE QUOTING A PRICE. Every row carries one, and it
says how much evidence is behind that number. Measured over the whole cube:

  direct      2.7%   30+ sales in the cell. Quote it plainly.
  modeled    15.4%   5-29 sales. Sound, lightly smoothed.
  suppressed 44.0%   1-4 sales. Indicative — say the sample is thin.
  imputed    17.3%   ZERO sales. The price is the prior BORROWED from a
                     parent geography, not a measurement of this cohort.
  missing    20.7%   zero sales and no price at all (null).

An `imputed` row looks exactly like a real one — a confident, specific
figure — and it repeats: in one district, 25 cohorts all read the same
353,909, because they are all the same borrowed number. Reporting it as
"2-bed detached in AL10 sell for £353,909" states a fact the data does not
contain. Say the cohort has no recorded sales instead, or aggregate up to a
grain that does. `turnover_rate` is 0 on every one of these rows, which is
a second tell.

Where you want the AREA rather than a cohort, do not read a cohort row and
call it the area: aggregate, or use `market_ranking`, which does it for you
weighted by the sales behind each cohort. There is no rollup row in this
cube — no `bedroom_band="all"` and no `hmo_flag="all"`; filtering on either
matches nothing at all.

`max_periods` (default 3) bounds how many recent MONTHLY periods come back
when `period` is not given. The grain is one row per (asset_subtype ×
bedroom_band × hmo_flag × period) — about 13 cohorts per period — so a wide
window gets large fast. The response reports `period_frequency`,
`periods_returned` and `truncated` so you can tell a short answer from a
cut-off one.

UK only. Free.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
periodNo
h3_cellNo
metricsNo
lad_codeNo
postcodeNo
lsoa_codeNo
ward_codeNo
asset_classNo
max_periodsNo
bedroom_bandNo
asset_subtypeNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly/idempotent/destructive=false), but the description goes far beyond them: it names the null metrics, warns that imputed rows are borrowed priors that look real, gives the tx_decision distribution, and cites the repeating-353,909 tell. This is exactly the kind of behavioral context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the one-line purpose and grain before the caveats, and each paragraph covers a distinct failure mode (null metrics, imputation, geography grain, rollup absence, truncation). It is long and repeats the 'don't rank on nulls / aggregate instead' idea, but the length is largely justified by the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter cube reader with an output schema present, the description supplies everything needed to call and interpret it: grain, valid geographies, the tx_decision evidence ladder, and the response fields (period_frequency, periods_returned, truncated, metrics_with_no_data). Only h3_cell is left unexplained, which is minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage the description must carry the params, and it does: postcode resolves to district (no sector/unit grain), lad_code is a NAME not a GSS code, max_periods defaults to 3 and bounds monthly periods, and period semantics are explained. Gaps remain — h3_cell is never mentioned and the accepted values of `metrics` are only implied by the populated/null list.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a precise verb+resource+grain: what it returns (sales_price, price_psm, turnover_rate) and the exact cube grain (geography × asset class × bedroom band × period). It also names the sibling tools it is not (market_ranking for area comparison, market_volume_series for counts), so an agent can route without opening another schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use and when-not: 'To compare AREAS against each other use market_ranking, not repeated calls here' and 'For "how many sales" use market_volume_series'. It further states that LSOA/ward selectors return 422 and that there is no rollup row, removing the most likely mis-invocations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources