Skip to main content
Glama

Cenogram - Polish Real Estate Data

get_permits_in_area

Read-only

List the building permits and works notifications registered since 2016 within a radius of a point - issued decisions only, matched through the parcel geometry we hold, which is near-complete but not the whole cadastre - to see what is being built nearby. Returns cases newest first, NOT nearest first (a permit and a notification for one investment are two cases), plus an aggregate by year and statutory object category over ALL matched cases (do not add it up across pages) with the permit/notification split and building volume. truncated = more cases than the limit: pass the returned cursor back with the same filters. Examples: apartment blocks → categories=[XIII]; drop utility-network noise (XXVI can be most of a list) → excludeCategories=[XXVI]; utility works as a sign that land is being serviced for development → categories=[XXVI]. For "how many / how much" pass aggregateOnly=true (same price). The list is by date: for what is closest use a smaller radiusKm (e.g. 0.3) instead of paging; radiusKm is 0.1–2 (default 2), for a wider area make several calls for neighbouring centres. Reading it: decision outcomes (granted or refused) are not held; notifications only where accepted without objection; pending cases not at all. Matching uses the parcel's current identifier and geometry, so cases filed before a split or merge may be missed, parcels without geometry are not searched and a number with a sheet segment may match less exactly. The answer states how many parcels we hold in the circle (0 = no data for the area) and the last refresh date (periodic, not live). A volume marked suspect stays in the sums. A short or empty list is never a statement that nothing is being built. A query over the time limit returns an error asking for a smaller radius. Coordinates: for a parcel use resolve_parcel (or resolve_parcel(prefix)); for a street list_parcels_in_area(location, street) and a returned row's centre point; otherwise from the user - never guess them. Cost: 5 API tokens per call, also for an empty list; each page is a separate call. Can be switched off for maintenance ("temporarily unavailable").

Input Schema

NameRequiredDescriptionDefault
latYesCircle centre latitude (WGS84, Poland); never guessed.
lngYesCircle centre longitude (WGS84, Poland); never guessed.
limitNoCases in the list, 1–200 (default 50).
cursorNoCursor from the previous answer (next page); pass it back unchanged with the same filters. Not with aggregateOnly.
dateToNoWindow end, YYYY-MM-DD, inclusive, not before dateFrom. When older than two years, pass dateFrom as well.
intentNomulti_family = categories [XIII], single_family = [I] (incl. semi-detached and terraced), all = no filter (default). Not with categories.
dateFromNoWindow start, YYYY-MM-DD (decision date; intake date for notifications). Default two years back; earlier than 2016-01-01 counts as 2016-01-01.
radiusKmNoRadius in km, 0.1–2 (default 2).
worksTypeNonew_construction (default) or all (adds extensions, demolitions and other works).
categoriesNoKeep only these object categories (Roman numerals I–XXX). Not with intent other than all; must not overlap excludeCategories.
aggregateOnlyNotrue = only the aggregate (year × category counts, split, volumes), no case list. Same price; not with cursor.
excludeCategoriesNoDrop these object categories (cases without a category stay). Must not overlap categories.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / properties / cursor / description
      Previous value: -"Cursor from the previous answer, for the next page; pass it back unchanged with the same filters. Not with aggregateOnly."New value: +"Cursor from the previous answer (next page); pass it back unchanged with the same filters. Not with aggregateOnly."
    • changedInput schema / properties / lat / description
      Previous value: -"Circle centre latitude (WGS84, Poland), from resolve_parcel / list_parcels_in_area or the user; never guessed."New value: +"Circle centre latitude (WGS84, Poland); never guessed."
    • changedInput schema / properties / limit / description
      Previous value: -"Cases in the list, 1–200 (default 50). The aggregate counts all matched cases."New value: +"Cases in the list, 1–200 (default 50)."
    • changedInput schema / properties / lng / description
      Previous value: -"Circle centre longitude (WGS84, Poland), from resolve_parcel / list_parcels_in_area or the user; never guessed."New value: +"Circle centre longitude (WGS84, Poland); never guessed."
  2. Changed11 schema fields changed
    • changedInput schema / properties / aggregateOnly / description
      Previous value: -"true = return only the aggregate (year × category counts, permit/notification split, volumes) without the case list, for 'how many' questions. Same price; cannot be combined with cursor."New value: +"true = only the aggregate (year × category counts, split, volumes), no case list. Same price; not with cursor."
    • changedInput schema / properties / categories / description
      Previous value: -"Keep only these statutory object categories (Roman numerals I–XXX), e.g. [\"XIII\"] for apartment blocks or [\"XXVI\"] for utility networks. Not combinable with intent other than all, and must not overlap with excludeCategories."New value: +"Keep only these object categories (Roman numerals I–XXX). Not with intent other than all; must not overlap excludeCategories."
    • changedInput schema / properties / cursor / description
      Previous value: -"Opaque cursor from the previous answer, to get the next page. Pass it back unchanged with the same filters (limit may differ); it is not available with aggregateOnly."New value: +"Cursor from the previous answer, for the next page; pass it back unchanged with the same filters. Not with aggregateOnly."
    • changedInput schema / properties / dateFrom / description
      Previous value: -"Window start, YYYY-MM-DD, on the decision date (intake date for notifications). Default: two years back; earlier than 2016-01-01 is treated as 2016-01-01."New value: +"Window start, YYYY-MM-DD (decision date; intake date for notifications). Default two years back; earlier than 2016-01-01 counts as 2016-01-01."
    • changedInput schema / properties / dateTo / description
      Previous value: -"Window end, YYYY-MM-DD, inclusive; not earlier than dateFrom. When it is older than two years, pass dateFrom as well (the default start is two years back)."New value: +"Window end, YYYY-MM-DD, inclusive, not before dateFrom. When older than two years, pass dateFrom as well."
    • changedInput schema / properties / excludeCategories / description
      Previous value: -"Remove these statutory object categories (cases without a category stay), e.g. [\"XXVI\"] to drop utility networks. Must not overlap with categories."New value: +"Drop these object categories (cases without a category stay). Must not overlap categories."
    • changedInput schema / properties / intent / description
      Previous value: -"Shorthand: multi_family = categories [XIII], single_family = categories [I] (includes semi-detached and terraced houses), all = no filter (default). Cannot be combined with categories."New value: +"multi_family = categories [XIII], single_family = [I] (incl. semi-detached and terraced), all = no filter (default). Not with categories."
    • changedInput schema / properties / lat / description
      Previous value: -"Latitude of the circle's centre (WGS84, Poland). From a resolve_parcel / list_parcels_in_area result or the user; never guessed."New value: +"Circle centre latitude (WGS84, Poland), from resolve_parcel / list_parcels_in_area or the user; never guessed."
    • changedInput schema / properties / limit / description
      Previous value: -"Cases in the list, 1–200 (default 50). The aggregate always counts all matched cases."New value: +"Cases in the list, 1–200 (default 50). The aggregate counts all matched cases."
    • changedInput schema / properties / lng / description
      Previous value: -"Longitude of the circle's centre (WGS84, Poland). From a resolve_parcel / list_parcels_in_area result or the user; never guessed."New value: +"Circle centre longitude (WGS84, Poland), from resolve_parcel / list_parcels_in_area or the user; never guessed."
    • changedInput schema / properties / radiusKm / description
      Previous value: -"Radius in km, 0.1–2 (default 2). For a wider area, call again for neighbouring centre points; for what is closest to the point, use a smaller radius."New value: +"Radius in km, 0.1–2 (default 2)."
  3. Changed9 schema fields changed
    • addedInput schema / properties / aggregateOnly
      Added value: +{
      +  "description": "true = return only the aggregate (year × category counts, permit/notification split, volumes) without the case list, for 'how many' questions. Same price; cannot be combined with cursor.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / categories
      Added value: +{
      +  "description": "Keep only these statutory object categories (Roman numerals I–XXX), e.g. [\"XIII\"] for apartment blocks or [\"XXVI\"] for utility networks. Not combinable with intent other than all, and must not overlap with excludeCategories.",
      +  "items": {
      +    "enum": [
      +      "I",
      +      "II",
      +      "III",
      +      "IV",
      +      "V",
      +      "VI",
      +      "VII",
      +      "VIII",
      +      "IX",
      +      "X",
      +      "XI",
      +      "XII",
      +      "XIII",
      +      "XIV",
      +      "XV",
      +      "XVI",
      +      "XVII",
      +      "XVIII",
      +      "XIX",
      +      "XX",
      +      "XXI",
      +      "XXII",
      +      "XXIII",
      +      "XXIV",
      +      "XXV",
      +      "XXVI",
      +      "XXVII",
      +      "XXVIII",
      +      "XXIX",
      +      "XXX"
      +    ],
      +    "type": "string"
      +  },
      +  "maxItems": 30,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • addedInput schema / properties / cursor
      Added value: +{
      +  "description": "Opaque cursor from the previous answer, to get the next page. Pass it back unchanged with the same filters (limit may differ); it is not available with aggregateOnly.",
      +  "maxLength": 300,
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / dateTo
      Added value: +{
      +  "description": "Window end, YYYY-MM-DD, inclusive; not earlier than dateFrom. When it is older than two years, pass dateFrom as well (the default start is two years back).",
      +  "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +  "type": "string"
      +}
    • addedInput schema / properties / excludeCategories
      Added value: +{
      +  "description": "Remove these statutory object categories (cases without a category stay), e.g. [\"XXVI\"] to drop utility networks. Must not overlap with categories.",
      +  "items": {
      +    "enum": [
      +      "I",
      +      "II",
      +      "III",
      +      "IV",
      +      "V",
      +      "VI",
      +      "VII",
      +      "VIII",
      +      "IX",
      +      "X",
      +      "XI",
      +      "XII",
      +      "XIII",
      +      "XIV",
      +      "XV",
      +      "XVI",
      +      "XVII",
      +      "XVIII",
      +      "XIX",
      +      "XX",
      +      "XXI",
      +      "XXII",
      +      "XXIII",
      +      "XXIV",
      +      "XXV",
      +      "XXVI",
      +      "XXVII",
      +      "XXVIII",
      +      "XXIX",
      +      "XXX"
      +    ],
      +    "type": "string"
      +  },
      +  "maxItems": 30,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • changedInput schema / properties / intent / description
      Previous value: -"multi_family = category XIII, single_family = category I (includes semi-detached and terraced houses), all = no filter (default)."New value: +"Shorthand: multi_family = categories [XIII], single_family = categories [I] (includes semi-detached and terraced houses), all = no filter (default). Cannot be combined with categories."
    • changedInput schema / properties / lat / description
      Previous value: -"Latitude of the circle's centre (WGS84, Poland). From a resolve_parcel / search_parcels result or the user; never guessed."New value: +"Latitude of the circle's centre (WGS84, Poland). From a resolve_parcel / list_parcels_in_area result or the user; never guessed."
    • changedInput schema / properties / lng / description
      Previous value: -"Longitude of the circle's centre (WGS84, Poland). From a resolve_parcel / search_parcels result or the user; never guessed."New value: +"Longitude of the circle's centre (WGS84, Poland). From a resolve_parcel / list_parcels_in_area result or the user; never guessed."
    • changedInput schema / properties / radiusKm / description
      Previous value: -"Radius in km, 0.1–2 (default 2). For a wider area, call again for neighbouring centre points."New value: +"Radius in km, 0.1–2 (default 2). For a wider area, call again for neighbouring centre points; for what is closest to the point, use a smaller radius."
  4. Added

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnly, non-destructive, closed-world, but the description adds genuinely new behavioural facts: sort order is date not distance, one investment can yield two cases, the aggregate spans ALL matched cases and must not be summed across pages, truncated/cursor semantics, silent error on time-limit overrun, 5-token cost even for empty results, periodic (not live) refresh, and possible maintenance shutdown. It also discloses coverage limits (near-complete but not whole cadastre, parcels without geometry unsearched, split/merge misses, missing decision outcomes) and warns that a short list is not evidence of no construction.

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?

Strongly front-loaded: purpose first, then return semantics, then worked examples, then interpretation caveats, then coordinates and cost - an agent can stop reading after the first sentence and still be safe. It is, however, a dense ~330-word block with a few restatements of schema constraints (radius range/default), so it is efficient rather than tight.

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 a 12-parameter tool with no output schema, the description covers return shape, ordering, aggregation behaviour, pagination, empty-result interpretation, data-refresh staleness and failure modes. There is nothing an agent needs to know to call it correctly or to avoid misreading its output that is missing here.

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 the baseline is 3, but the description earns extra by giving concrete category-to-intent mappings, the excludeCategories-vs-categories interplay, the 'same price' rationale for aggregateOnly, and the tradeoff between radiusKm and paging. Some content merely restates schema facts (radiusKm 0.1-2 default 2), which keeps it short of a 5.

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 specific verb, resource and scope: lists building permits and works notifications within a radius since 2016, issued decisions only, matched via parcel geometry. It also states up front what the tool is for ('to see what is being built nearby') and distinguishes itself from resolve_parcel / list_parcels_in_area, which it names as the coordinate sources rather than as competitors.

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 routing advice is given for each mode: category examples (apartment blocks -> XIII, utility noise -> excludeCategories XXVI, utility works as a servicing signal -> XXVI), aggregateOnly=true for 'how many / how much', a smaller radiusKm instead of paging for proximity, and several calls around neighbouring centres for wider areas. Coordinate sourcing is prescribed (resolve_parcel, list_parcels_in_area, or the user - 'never guess them'), which is exactly the when/when-not guidance an agent needs.

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