Skip to main content
Glama
cenogram-mcp-server

cenogram-mcp-server

Official

search_by_area

Read-only

Locate Polish property transactions (deeds and prices) within a radius around coordinates for street, neighborhood, or city-area searches.

Instructions

Find transactions within a radius of a point - the tool for neighborhoods/osiedla (not TERYT districts) and street-level searches. Returns TRANSACTIONS (deeds and prices), despite the name; for the land plots themselves in an area use list_parcels_in_area. Radius: 0.3-0.5 km for a street, 0.5-1 km for a neighborhood, 2-5 km for a city area; the area is a bounding box around the radius, so corners extend beyond radiusKm. Take coordinates from the user, never invent them. minArea/maxArea work for every propertyType. Costs 3 API tokens (1 with summaryOnly). Permalink to a result: https://cenogram.pl/ceny-transakcyjne?src=mcpstdio#v=1&lat=&lng=&z=16&tx= ( from the "id:" line, / from "Location: °N, °E"; omit &tx= for the area only).

Input Schema

NameRequiredDescriptionDefault
pageNoPage 1-10 (50 rows).
floorNoUnit floor, multi-select: integers ('0' = parter, negatives = basement), 'Nplus' ('0plus' = ground and above), 'unknown' (none recorded). Not building storeys; rows with no floor drop out unless 'unknown' is listed.
limitNoNumber of results (1-50, default 20)
roomsNoRooms (izby), residential units only; multi-select ('8plus' = 8 or more). Rows with no count drop out unless 'unknown' is listed.
dateToNoEnd date (YYYY-MM-DD)
landUseNoLand-use category, multi-select, case-sensitive (gruntyZabudowaneIZurbanizowane = built-up, gruntyRolne = agricultural, gruntyLesne = forest, terenyKomunikacyjne = transport); 'unknown' = none recorded (NULL), not 'no use'.
maxAreaNoMaximum area in m²
minAreaNoMinimum area in m² (usable area for units, parcel area for land)
dateFromNoStart date (YYYY-MM-DD)
latitudeYesLatitude (Poland range: 49-55)
maxPriceNoMaximum price in PLN
minPriceNoMinimum price in PLN
radiusKmNoSearch radius in km (0.1-50, default 2).
floodRiskNoFlood-hazard zone, multi-select: high ~1-in-10-year, medium ~1-in-100, low ~1-in-500. Mapped zones only; absence of a zone is never 'safe'.
longitudeYesLongitude (Poland range: 14-25)
marketTypeNoprimary (developer) or secondary (resale); the ~55% of records with no market type drop out when this is set.
summaryOnlyNoReturn only aggregate stats (total, median price/m² with its sample size, period) and no rows. Costs only the summary call; limit/sort/page are ignored.
buildingTypeNoBuilding type (PKOB); 'unknown' = none recorded (NULL, ~39% of buildings), any other value excludes such rows.
propertyTypeNoProperty type filter
unitFunctionNoUnit function; 'unknown' = none recorded (NULL), any other value excludes such rows. Garages only via 'garage'.
landslideRiskNoLandslide hazard, multi-select: landslide = mapped landslide area; threatened = area threatened by mass movements. Mapped areas only; absence of a zone is never 'safe'.
ownershipTypeNoLegal-right type (rodzaj prawa), multi-select; perpetual_usufruct = użytkowanie wieczyste; 'unknown' = none recorded.
heritageStatusNoHeritage listing, multi-select: listed = protected monument on the land; zone = protected urban layout or monument surroundings. Detected listings only; absence of a detection is never 'not listed'.
buildingStoreysNoAbove-ground storeys, multi-select: integers, 'Nplus' ('3plus' = 3+), 'unknown' (no count). Single-building deeds only, so 'unknown' also covers multi-building deeds. Not the unit floor; rows with no count drop out unless 'unknown' is listed.
mpzpDesignationNoMPZP zoning designation, exact token match; comma-separated = OR; 'unknown' = none recorded. Same codes as search_transactions mpzpDesignation.
transactionTypeNoMulti-select. For market analysis ALWAYS set it to exclude non-market deeds (subsidized, foreclosure, public_purpose); no-type rows (~2%) drop out unless 'unknown' is listed.
maxFootprintAreaNoMaximum building footprint in m², summed over the transaction's buildings; measured rows only (absence = 'not measured', not 'no building'). Not usable area.
minFootprintAreaNoMinimum building footprint in m², summed over the transaction's buildings; measured rows only (absence = 'not measured', not 'no building'). Not usable area.
excludeFractionalSharesNotrue = clean land prices: drops fractional ownership shares, whose price reflects the whole deed. Default false.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed20 schema fields changedv0.18.0
    • changedInput schema / properties / buildingStoreys / description
      Previous value: -"Number of above-ground storeys of the building. Multi-select buckets: exact non-negative integers (e.g. '1','2'), 'Nplus' e.g. '3plus' = 3 or more, 'unknown' = no storey count recorded (NULL). Recorded ONLY for single-building transactions, so 'unknown' covers BOTH a deed with several buildings (no single storey count exists) and a single building with missing data — never read it as 'a building with no storeys'. This is NOT the floor of a unit (see floor). Without 'unknown', rows with no storey count are excluded."New value: +"Above-ground storeys, multi-select: integers, 'Nplus' ('3plus' = 3+), 'unknown' (no count). Single-building deeds only, so 'unknown' also covers multi-building deeds. Not the unit floor; rows with no count drop out unless 'unknown' is listed."
    • changedInput schema / properties / buildingType / description
      Previous value: -"Building type filter (PKOB classification). 'unknown' = no type recorded (NULL); without it such rows are excluded (~39% of buildings have no type)."New value: +"Building type (PKOB); 'unknown' = none recorded (NULL, ~39% of buildings), any other value excludes such rows."
    • addedInput schema / properties / excludeFractionalShares
      Added value: +{
      +  "default": false,
      +  "description": "true = clean land prices: drops fractional ownership shares, whose price reflects the whole deed. Default false.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / floodRisk / description
      Previous value: -"Flood-hazard filter. high = most frequent flooding (~1-in-10-year), medium (~1-in-100-year), low = rarest (~1-in-500-year). Selects ONLY transactions whose land sits in a mapped flood zone; absence of a zone is never asserted as 'safe'. Multi-select; e.g. ['medium','high'] = at least medium risk."New value: +"Flood-hazard zone, multi-select: high ~1-in-10-year, medium ~1-in-100, low ~1-in-500. Mapped zones only; absence of a zone is never 'safe'."
    • changedInput schema / properties / floor / description
      Previous value: -"Floor of the unit (piętro lokalu, residential). Multi-select buckets: exact integers incl. '0' (parter) and negatives e.g. '-1' (basement), 'Nplus' e.g. '10plus' = 10 or more, '0plus' = ground and above, 'unknown' = no floor recorded (NULL). E.g. ['0','1','2'] for ground-to-2nd floor. Building storeys are a different attribute. Without 'unknown', rows with no floor are excluded."New value: +"Unit floor, multi-select: integers ('0' = parter, negatives = basement), 'Nplus' ('0plus' = ground and above), 'unknown' (none recorded). Not building storeys; rows with no floor drop out unless 'unknown' is listed."
    • changedInput schema / properties / heritageStatus / description
      Previous value: -"Heritage-listing filter. listed = a protected monument on/at the property's land; zone = the land lies within a protected urban layout or the designated surroundings of a monument. Selects ONLY transactions where a listing was detected; absence of a detection is never asserted as 'not listed'. Multi-select; e.g. ['listed'] = individually listed properties only."New value: +"Heritage listing, multi-select: listed = protected monument on the land; zone = protected urban layout or monument surroundings. Detected listings only; absence of a detection is never 'not listed'."
    • changedInput schema / properties / landUse / description
      Previous value: -"Recorded land-use category of the transaction's land. Multi-select from: gruntyZabudowaneIZurbanizowane (built-up and urbanised), gruntyRolne (agricultural), gruntyLesne (forest), terenyKomunikacyjne (transport), inne (other). 'unknown' = no category recorded for the land (NULL) — a legitimate bucket, never a claim that the land has no use. Values are case-sensitive. E.g. ['gruntyRolne'] for farmland, or ['gruntyZabudowaneIZurbanizowane','gruntyRolne'] to compare developed vs farmland."New value: +"Land-use category, multi-select, case-sensitive (gruntyZabudowaneIZurbanizowane = built-up, gruntyRolne = agricultural, gruntyLesne = forest, terenyKomunikacyjne = transport); 'unknown' = none recorded (NULL), not 'no use'."
    • changedInput schema / properties / landslideRisk / description
      Previous value: -"Landslide-hazard filter, from official landslide-hazard maps (1:10,000 scale). 'landslide' = the land intersects a mapped landslide area; 'threatened' = an area threatened by mass movements. Selects ONLY transactions whose land intersects a mapped hazard area — an intersection means overlap with a mapped area, not that the parcel itself is a landslide; absence of a zone is never asserted as 'safe'. Multi-select; e.g. ['landslide','threatened'] = any mapped hazard."New value: +"Landslide hazard, multi-select: landslide = mapped landslide area; threatened = area threatened by mass movements. Mapped areas only; absence of a zone is never 'safe'."
    • changedInput schema / properties / marketType / description
      Previous value: -"Market type: primary (developer) or secondary (resale). ~55% of records have unknown market type and will be excluded when this filter is used."New value: +"primary (developer) or secondary (resale); the ~55% of records with no market type drop out when this is set."
    • changedInput schema / properties / maxFootprintArea / description
      Previous value: -"Maximum building footprint (ground-plan) area in m², summed over all buildings of the transaction. Distinct from maxArea, which measures usable floor area (units) or land/parcel area. Set only where every linked building has footprint data, so this bound selects only measured rows — absence means 'not measured', not 'no building'."New value: +"Maximum building footprint in m², summed over the transaction's buildings; measured rows only (absence = 'not measured', not 'no building'). Not usable area."
    • changedInput schema / properties / minArea / description
      Previous value: -"Minimum area in m² (usable_area_m2 for units, parcel_area for land)"New value: +"Minimum area in m² (usable area for units, parcel area for land)"
    • changedInput schema / properties / minFootprintArea / description
      Previous value: -"Minimum building footprint (ground-plan) area in m², summed over all buildings of the transaction. Distinct from minArea, which measures usable floor area (units) or land/parcel area. Set only where every linked building has footprint data, so this bound selects only measured rows — absence means 'not measured', not 'no building'."New value: +"Minimum building footprint in m², summed over the transaction's buildings; measured rows only (absence = 'not measured', not 'no building'). Not usable area."
    • addedInput schema / properties / mpzpDesignation
      Added value: +{
      +  "description": "MPZP zoning designation, exact token match; comma-separated = OR; 'unknown' = none recorded. Same codes as search_transactions mpzpDesignation.",
      +  "type": "string"
      +}
    • changedInput schema / properties / ownershipType / description
      Previous value: -"Ownership / legal-right type filter (rodzaj prawa do nieruchomości). land_ownership; perpetual_usufruct (użytkowanie wieczyste — covers both registry codes for this right); cooperative_ownership; unit_sale; ownership; unit_ownership_with_appurtenant_right; building_ownership_with_appurtenant_right. 'unknown' = no right recorded (NULL). Multi-select; e.g. ['land_ownership','perpetual_usufruct'] to compare ownership vs perpetual usufruct on undeveloped land."New value: +"Legal-right type (rodzaj prawa), multi-select; perpetual_usufruct = użytkowanie wieczyste; 'unknown' = none recorded."
    • addedInput schema / properties / page
      Added value: +{
      +  "description": "Page 1-10 (50 rows).",
      +  "maximum": 10,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • changedInput schema / properties / radiusKm / description
      Previous value: -"Search radius in km (0.1-50, default 2). Use 0.5-1 for neighborhoods, 0.3-0.5 for streets."New value: +"Search radius in km (0.1-50, default 2)."
    • changedInput schema / properties / rooms / description
      Previous value: -"Number of rooms (izby) filter, residential units only. Multi-select; '8plus' means 8 or more, 'unknown' = no room count recorded (NULL). E.g. ['2','3'] for 2-3 izby flats. Without 'unknown', rows with no room count are excluded."New value: +"Rooms (izby), residential units only; multi-select ('8plus' = 8 or more). Rows with no count drop out unless 'unknown' is listed."
    • addedInput schema / properties / summaryOnly
      Added value: +{
      +  "description": "Return only aggregate stats (total, median price/m² with its sample size, period) and no rows. Costs only the summary call; limit/sort/page are ignored.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / transactionType / description
      Previous value: -"Transaction type filter. For market analysis, ALWAYS specify to exclude non-market transactions."New value: +"Multi-select. For market analysis ALWAYS set it to exclude non-market deeds (subsidized, foreclosure, public_purpose); no-type rows (~2%) drop out unless 'unknown' is listed."
    • changedInput schema / properties / unitFunction / description
      Previous value: -"Unit/apartment function filter. 'unknown' = no function recorded (NULL); without it such rows are excluded. Garages appear only when 'garage' is selected, not via 'unknown'."New value: +"Unit function; 'unknown' = none recorded (NULL), any other value excludes such rows. Garages only via 'garage'."
  2. Changed4 schema fields changedv0.12.0
    • addedInput schema / properties / buildingStoreys
      Added value: +{
      +  "description": "Number of above-ground storeys of the building. Multi-select buckets: exact non-negative integers (e.g. '1','2'), 'Nplus' e.g. '3plus' = 3 or more, 'unknown' = no storey count recorded (NULL). Recorded ONLY for single-building transactions, so 'unknown' covers BOTH a deed with several buildings (no single storey count exists) and a single building with missing data — never read it as 'a building with no storeys'. This is NOT the floor of a unit (see floor). Without 'unknown', rows with no storey count are excluded.",
      +  "items": {
      +    "pattern": "^(\\d+|\\d+plus|unknown)$",
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / landUse
      Added value: +{
      +  "description": "Recorded land-use category of the transaction's land. Multi-select from: gruntyZabudowaneIZurbanizowane (built-up and urbanised), gruntyRolne (agricultural), gruntyLesne (forest), terenyKomunikacyjne (transport), inne (other). 'unknown' = no category recorded for the land (NULL) — a legitimate bucket, never a claim that the land has no use. Values are case-sensitive. E.g. ['gruntyRolne'] for farmland, or ['gruntyZabudowaneIZurbanizowane','gruntyRolne'] to compare developed vs farmland.",
      +  "items": {
      +    "enum": [
      +      "gruntyZabudowaneIZurbanizowane",
      +      "gruntyRolne",
      +      "gruntyLesne",
      +      "terenyKomunikacyjne",
      +      "inne",
      +      "unknown"
      +    ],
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedInput schema / properties / maxFootprintArea
      Added value: +{
      +  "description": "Maximum building footprint (ground-plan) area in m², summed over all buildings of the transaction. Distinct from maxArea, which measures usable floor area (units) or land/parcel area. Set only where every linked building has footprint data, so this bound selects only measured rows — absence means 'not measured', not 'no building'.",
      +  "type": "number"
      +}
    • addedInput schema / properties / minFootprintArea
      Added value: +{
      +  "description": "Minimum building footprint (ground-plan) area in m², summed over all buildings of the transaction. Distinct from minArea, which measures usable floor area (units) or land/parcel area. Set only where every linked building has footprint data, so this bound selects only measured rows — absence means 'not measured', not 'no building'.",
      +  "type": "number"
      +}
  3. First observedv0.5.0

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the readOnlyHint annotation: it discloses token cost (3 API tokens, 1 with summaryOnly), the bounding-box approximation that makes corners extend past radiusKm, and the exact permalink construction including which output fields to substitute. That is unusually rich context for a read-only tool.

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-loaded purpose sentence followed by short labeled blocks (radius guidance, cost, permalink), so it scans well. Slightly dense with the permalink template, but no sentence is filler.

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

Completeness4/5

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

With 29 parameters and no output schema, it still tells the agent what comes back (deeds and prices), what the id/Location lines look like, and how to build a permalink. Minor gaps around ordering/sort behavior, but nothing that would cause a wrong call.

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?

Schema coverage is 100%, so baseline is 3, but the description adds cross-parameter meaning the schema lacks: radius sizing per search intent, that the area is a bounding box, that minArea/maxArea apply to every propertyType, and that summaryOnly makes limit/sort/page irrelevant.

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?

States a specific verb and resource ('Find transactions within a radius of a point') and explicitly disambiguates from the name itself ('Returns TRANSACTIONS, despite the name'), while naming list_parcels_in_area as the alternative for parcels. An agent can pick it apart from search_transactions or search_by_polygon without opening the 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?

Gives concrete when-to-use conditions (neighborhoods/osiedla rather than TERYT districts, street-level searches), names the direct alternative for a different need, and adds operational rules: radius 0.3-0.5 km for a street, 2-5 km for a city area, and 'Take coordinates from the user, never invent them.'

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