deweloperuch-mcp
Read-only MCP server and CLI for Polish new-build housing data: search and analyze developer offers, price histories, investments, developers, transaction prices, official statistics, and approximate valuations.
Find cities, districts, streets, developers, offers, and investments by name or slug.
Search active/archived apartment offers by city, price, area, price/m², district, price drop, with sorting and pagination.
Inspect one offer’s full price history, recent lowest prices, and suspicious-reduction flags.
Explore investments and developer profiles: projects, active offers, average prices, cities, and links.
Get city-level offer-market statistics: counts, price/area distributions, and top developers.
Analyze RCN transaction prices over time, rank locations/powiats, and inspect building transactions.
Estimate an apartment’s value from nearby RCN comparables.
Retrieve GUS/NBP/Eurostat time series for dwellings, prices, wages, unemployment, population, and demography.
Use as an MCP server in compatible clients or through the
deweloperuchCLI; all tools are read-only.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@deweloperuch-mcpFind 40–55 m² flats in Kraków's Podgórze under 800,000 PLN, cheapest per m² first."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Ask an AI assistant about new-build apartments in Poland: asking prices with their history, real transaction prices and official statistics.
An unofficial MCP server and command-line tool over the public data of deweloperuch.pl: developers' asking prices (with price history), transaction prices from the Real Estate Price Register (RCN) and statistics of GUS, NBP and Eurostat. Thirteen read-only tools, usable from an MCP client such as Claude Desktop or Claude Code, or from the deweloperuch CLI.
Disclaimer. This is an independent project. It is not affiliated with, endorsed by or sponsored by deweloperuch.pl, GUS, NBP or the Register's publishers. The authors of deweloperuch.pl have agreed to the project's use of their service; the client identifies itself as
deweloperuch-mcp/<version>with a link to this repository.
It is read-only: it never creates or changes anything on the service.
It is a polite client: at most 1 request per second, one at a time, shared by all processes on your machine; responses are cached; after a 401, 403, 429 or a captcha/WAF challenge it stops sending requests until you clear the lock yourself.
Please respect the service. It is run by other people; ask narrow questions and do not build loops or bulk downloads on top of this tool.
Data accuracy is not guaranteed. Prices are asking or registered prices, not valuations or advice.
You are responsible for how you use the tool and the data, including the terms of the service.
What you can ask
Buying a flat: "Find flats of 40–55 m² in Kraków's Podgórze up to 800 000 PLN, cheapest per m² first." (The service has no filter by number of rooms; filter by area instead.)
Judging an offer's price: "Is this offer a good deal? Show its price history, the lowest price of the last 30 and 90 days, and whether the reduction looks suspicious."
Checking a developer: "What does this developer build, and how many offers are active in which cities?"
Market and transaction prices: "How do asking prices in Gdańsk compare with registered transaction prices over the last quarters?"
Valuation: "Roughly what is a 55 m² flat at this address worth, based on nearby transactions?"
Comparing cities: "Rank cities by transaction price per m², and show wages and unemployment next to them."
Related MCP server: korea-realty
Install
Pick the first option that fits you; they go from no terminal to expert. Supported systems: macOS, Linux and Windows 10 (1903+) / 11 with a local NTFS cache directory.
Windows is supported starting with 0.1.3, including the PyPI package and .mcpb extension. Releases up to 0.1.2 support macOS and Linux only.
Prefer a visual walkthrough? The install guide on the project's website (in Polish) shows the installation step by step and has a prompt that lets an AI agent install it for you.
1. Claude Desktop, no terminal
Download
deweloperuch-mcp-<version>.mcpbfrom the latest release.Double-click it, or drag it into Claude Desktop → Settings → Extensions → Install, then restart Claude Desktop.
You get: the 13 tools and 4 prompts in Claude Desktop. The extension uses the uv runtime (server.type is uv in its manifest), so the first start fetches Python and the dependencies and takes about a minute; you install nothing yourself. It has no command-line tool; if the server is ever stopped (STOP), see lifting a STOP without a checkout.
2. Any MCP client, with uv
You get: the same tools in Claude Desktop, Claude Code or any client that starts a stdio server. Nothing to clone.
Install uv once (macOS and Linux):
curl -LsSf https://astral.sh/uv/install.sh | shOn Windows, use PowerShell (uv installation):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Open a new terminal after installation so it sees uv on PATH.
Claude Code:
claude mcp add deweloperuch -- uvx deweloperuch-mcpClaude Desktop (claude_desktop_config.json; other clients use the same command and args):
{
"mcpServers": {
"deweloperuch": {
"command": "uvx",
"args": ["deweloperuch-mcp"]
}
}
}To run straight from GitHub instead of PyPI, use uvx --from git+https://github.com/MBratkowski/deweloperuch-mcp@v0.1.3 deweloperuch-mcp (@v0.1.3 pins the release; drop it to follow main). pip install deweloperuch-mcp works too.
If a Windows MCP client cannot find uvx, use the full executable path from (Get-Command uvx).Source as command. Escape backslashes in JSON, for example "C:\\Users\\YOUR_NAME\\.local\\bin\\uvx.exe". A source checkout instead uses "command": "uv" and "args": ["run", "--directory", "C:\\path\\to\\deweloperuch-mcp", "deweloperuch-mcp"].
3. Agent skill for the CLI
You get: an AI coding agent that knows how to use the deweloperuch CLI (which command to call, how to read the output, what to do on STOP), without an MCP server. The skill is called deweloperuch-cli; a new agent session loads it by itself.
npx skills add MBratkowski/deweloperuch-mcpThis uses the skills CLI (needs Node.js) and works with any agent it supports; you choose the agent. Without Node.js:
uvx --from deweloperuch-mcp deweloperuch skill installIt writes to ~/.claude/skills/deweloperuch-cli (Claude Code, for the user). Options: --project (this project's ./.claude/skills), --agent codex|cursor|gemini-cli|github-copilot, --dir PATH (writes PATH/deweloperuch-cli), --force (replace a different copy; without it a changed copy is never overwritten, and the installer never writes through symlinks). deweloperuch skill show prints the skill, deweloperuch skill path its folder. Details: docs/cli/commands/skill.md.
Claude Code plugin marketplace:
/plugin marketplace add MBratkowski/deweloperuch-mcp
/plugin install deweloperuch@deweloperuch-mcp4. The CLI on its own
You get: the deweloperuch command for your terminal and scripts; see docs/cli/README.md.
uvx --from deweloperuch-mcp deweloperuch --help # one-off, nothing installed
uv tool install deweloperuch-mcp # installs deweloperuch and deweloperuch-mcp
deweloperuch locations search krak5. From source (contributors)
Requirements: Python 3.11 or newer and uv.
git clone https://github.com/MBratkowski/deweloperuch-mcp.git
cd deweloperuch-mcp
uv sync
uv run deweloperuch --help # sends no requestsAs the client command use uv run --directory /path/to/deweloperuch-mcp deweloperuch-mcp (Claude Code: claude mcp add deweloperuch -- uv run --directory /path/to/deweloperuch-mcp deweloperuch-mcp). More: CONTRIBUTING.md and docs/mcp/README.md.
Troubleshooting
uvx: command not foundorspawn uvx ENOENT: install uv (option 2). Claude Desktop may not see your shellPATH, so put the full path fromwhich uvx(macOS/Linux) or(Get-Command uvx).Source(PowerShell) incommand.The server does not appear in Claude Desktop: quit and restart Claude Desktop after installing the extension or editing the config.
Windows with release 0.1.2 or earlier: update to 0.1.3 or newer. For a uv tool installation, run
uv tool upgrade deweloperuch-mcp; for pip, runpython -m pip install --upgrade deweloperuch-mcp; foruvx, runuvx --refresh deweloperuch-mcp --help. Replace an older.mcpbextension with the latest release.STOP / exit code 3: after a 401, 403, 429 or a captcha/WAF challenge the client stops sending requests in every process, so as not to burden the service. A 429 expires by itself after the pause (at least 60 s). The other causes last until you lift them, after checking the cause (
deweloperuch stop statusshows the state; an AI agent must not lift it). The MCP server stays halted until you restart it. Details and the command: docs/configuration.md.Where is the cache? Responses are cached in memory only. The limiter lock and the STOP record live in
~/.cache/deweloperuch-mcp($XDG_CACHE_HOME/deweloperuch-mcp). Do not delete that directory: it would also lift a STOP.
Tools
Overview, argument rules, errors and result sizes: docs/mcp/README.md.
Tool | Description |
Finds cities, districts and streets by a name fragment and returns | |
A page of developers' apartment offers in a city or one of its districts, with price, area, price-per-m², district, status and price-drop filters and sorting. | |
One offer with its full price history and price flags (lowest price in 30/90 days, suspicious reduction). | |
Investments of a city (averages, sorting, filter by developer) or by name across Poland. | |
An investment with its developer, average prices and a list of offers, optionally with each offer's price history. | |
Finds developers by a name fragment and returns | |
A developer profile: summary, investments with active offers and cities. | |
Offer-market statistics of one city as of a day: counts, price, price per m² and area distributions, the largest developers. | |
Transaction prices (RCN) of a city by month or quarter, since 2017; months: secondary market only. | |
A ranking of places or powiats by RCN transactions and price per m², or of the 66 cities with powiat rights by a GUS or NBP indicator. | |
A building from the RCN with its units and transactions. | |
An approximate apartment value at a point from nearby RCN transactions. | |
Official GUS, NBP and Eurostat time series (dwellings, NBP prices, unemployment, wages, demography) for Poland, aggregates and 66 cities. |
Every tool rejects arguments that are not in its schema with an error that lists the allowed names. Tool descriptions, error messages and CLI output are in Polish, because the service and its users are Polish.
Prompts
Four ready-made prompts appear in Claude Desktop as commands. They send no requests themselves; they guide the model through the tools above. Arguments and details: docs/mcp/prompts.md.
Prompt | Description |
| Flats from developers in one city with a budget, area and district: a table of offers from the lowest price per m². |
| A price assessment of one offer: price history, comparison with the city market and with the valuation from nearby transactions. |
| A developer profile: where and how much it builds, its investments, active offers, prices and their changes. |
| A comparison of the flat market of several cities (at most 5) in one table: asking prices, RCN transaction prices, optionally wages and unemployment. |
CLI commands
Overview, output format and exit codes: docs/cli/README.md.
Command | Description |
Finds cities, districts and streets; returns the city slug. | |
Searches offers in a city or one of its districts with filters and sorting. | |
Shows an offer with its price history and price flags. | |
Searches investments of a city or by name. | |
Shows an investment with its developer and offers. | |
Finds developers by name; returns the developer slug. | |
Shows a developer profile. | |
Shows a building from the RCN with its units and transactions. | |
Estimates an apartment's value at a point. | |
Shows offer-market statistics of one city as of a day. | |
Shows RCN transaction prices of a city by month or quarter, since 2017; months: secondary market only. | |
Shows a ranking of places or powiats by RCN transactions, or of the 66 cities with powiat rights by a GUS or NBP indicator. | |
Shows GUS and NBP statistics (Eurostat for the demography of Poland) of a location as a table of periods. | |
Shows the STOP lock shared by all processes (offline; exit code 3 when active). | |
Clears the STOP lock, after you have checked the cause. | |
Installs, prints or locates the |
How it works
deweloperuch.pl → api → models → usecases → consumers (CLI, MCP server)Layer | Role |
| Talks to the service: an HTTP transport with the shared limiter, cache and STOP lock; readers for its JSON API and page data; DTOs that map responses to models. |
| Plain frozen dataclasses (offers, investments, price history, statistics). No I/O. |
| One module per operation (for example |
| The CLI and the MCP server, both thin: they parse arguments, call a use case and present the result. |
The layers are wired in bootstrap.py; tooling/ holds non-business helpers (the skill installer) that only the CLI uses. Import-linter enforces the direction of imports. Design decisions and their reasons: docs/decisions.md. The service's data, endpoints and limits: docs/discovery/README.md. Configuration, the limiter and the STOP lock: docs/configuration.md.
Development
uv sync
make fast # ruff, ruff format --check, mypy, import-linter (a few seconds)
make check # fast + the offline tests + dead-code check + complexity and duplication reportsEvery make target is offline; the tests never open a network socket and run against real responses stored in docs/discovery/samples/ and tests/fixtures/.
Folder | Contents |
| Unit tests mirroring |
| Stored service responses against the DTOs and adapters. |
| Use cases with the real adapters over a mocked service. |
| Golden outputs of the CLI and MCP server ( |
| Layering and naming rules, repository-wide consistency (identity, published assets, metadata); no-network guarantees. |
| Test infrastructure (fakes, builders, checks), no tests. |
| The opt-in live suite, see below. |
After an intended output change, refresh the golden outputs with DEWELOPERUCH_UPDATE_GOLDEN=1 uv run pytest tests/characterization and review the diff (tests/golden/README.md).
Live end-to-end tests are off by default. They check the installed server, the CLI and the helper scripts against the real service, so they send real requests. Run them sparingly, only when a change needs it:
DEWELOPERUCH_LIVE=1 uv run pytest -m live tests/e2e -rs --maxfail=3Both the variable and -m live are required. Scenarios and request budget: tests/e2e/README.md. Contributing guide and release procedure: CONTRIBUTING.md.
Documentation
Document | Contents |
The project's landing page and user documentation in Polish, with a visual install guide | |
The MCP server: tools, prompts, client configuration, argument rules, errors, result sizes | |
The | |
Environment variables, files, the request limiter, the cache and the STOP lock | |
Map of the data layer: service architecture, access channels, key findings | |
Catalog of the service's | |
Pages as a data source: filters, sorting, pagination | |
Entities, identifiers, relations, value dictionaries | |
Trimmed response samples (the basis of the contract tests) | |
Capabilities, the requests behind them and the tool or command that exposes them | |
Known gaps and unverified assumptions about the service | |
Architecture decisions | |
Changes between versions |
Data sources and licences
deweloperuch.pl: the source of all offer, investment, developer and statistics data. Its terms apply to your use of the data.
RCN (Real Estate Price Register) transaction data, reached through the service. The service's authors publish raw RCN data as CC0 in their public repository.
GUS (Central Statistical Office), NBP (National Bank of Poland) and Eurostat (the monthly demography of Poland) statistics, reached through the service. Name them as the source when you republish figures.
The code is licensed under the MIT licence. The licence covers code only; the samples and fixtures used for testing contain data from the sources above and are described in NOTICE. The project's icon is not covered by the MIT licence either: all rights reserved, used with permission of the deweloperuch.pl authors (see NOTICE).
Contributing
Issues and pull requests are welcome; please read CONTRIBUTING.md first, especially the polite-client rules. Security reports: SECURITY.md.
Available Tools
13 toolsestimate_property_valueWycena mieszkaniaARead-only
Szacuje wartość mieszkania o danym metrażu w punkcie (lat, lng) w Polsce na podstawie cen transakcyjnych z Rejestru Cen Nieruchomości (RCN) z okolicy. Wynik jest przybliżony: to porównanie z transakcjami w pobliżu, a nie operat szacunkowy. Użyj, gdy użytkownik pyta, ile może być warte mieszkanie albo czy jego cena jest rynkowa.
Zwraca estimated_value (PLN), price_per_m2, radius_m i period_months (skąd i z ilu miesięcy są transakcje), stats (liczba, mediana, średnia, min i max ceny za m²) oraz comparables: najbliższe transakcje porównawcze (adres, data, cena, metraż, cena za m², piętro, odległość, rynek), z comparables_total, comparables_omitted, truncated i hint. estimated_value=null znaczy, że serwis nie podał wyceny: przeczytaj hint. low_confidence=true (mniej niż 5 transakcji porównawczych): wycenę podaj tylko jako orientacyjną, z zastrzeżeniem z hint.
Wymaga współrzędnych: narzędzie nie zamienia adresu na lat i lng. Weź je od użytkownika, z search_locations (ulica lub dzielnica: to punkt przybliżony, nie konkretny budynek) albo z get_investment (współrzędne inwestycji oferty). Każde wywołanie to zapytanie do serwisu: nie wyceniaj seriami wielu punktów.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | Szerokość geograficzna punktu w Polsce w stopniach, np. 52.2297: pole lat z search_locations (ulica albo dzielnica, nie samo miasto) albo ze współrzędnych inwestycji w get_investment (dokładniejsze dla konkretnej oferty). | |
| lng | Yes | Długość geograficzna punktu w Polsce w stopniach, np. 21.0122: pole lng z search_locations (ulica albo dzielnica, nie samo miasto) albo ze współrzędnych inwestycji w get_investment (dokładniejsze dla konkretnej oferty). | |
| limit | No | Ile najbliższych transakcji porównawczych zwrócić, 0–50, domyślnie 10. Transakcja to ok. 210 znaków wyniku (50 to ok. 10,6 tys.); 0 = tylko wycena i statystyki. | |
| address | No | Opcjonalny opis adresu, np. Marszałkowska 100, Warszawa. Trafia do serwisu, ale nie wyznacza położenia: decydują lat i lng. | |
| area_m2 | Yes | Metraż mieszkania w m², 10–500, np. 48.5. |
Output Schema
| Name | Required | Description |
|---|---|---|
| lat | Yes | |
| lng | Yes | |
| hint | No | Co zrobić dalej. |
| stats | No | Statystyki cen za m² podane przez serwis. |
| area_m2 | Yes | Metraż podany w zapytaniu w m². |
| radius_m | No | Promień w metrach, z którego są transakcje porównawcze. |
| truncated | Yes | true: lista comparables jest niepełna (comparables_omitted > 0). |
| comparables | Yes | Transakcje porównawcze od najbliższych, najwyżej limit. |
| price_per_m2 | No | Szacowana cena za m² w PLN. |
| period_months | No | Z ilu ostatnich miesięcy są transakcje porównawcze. |
| low_confidence | No | true: wycena o niskiej wiarygodności (mniej niż 5 transakcji porównawczych); hint mówi, na czym się opiera. Podaj ją tylko jako orientacyjną, z zastrzeżeniem z hint. Jest przy każdej wycenie, brak przy estimated_value=null. |
| estimated_value | Yes | Szacowana wartość mieszkania w PLN podana przez serwis: przybliżenie, nie operat szacunkowy. null: serwis nie podał wyceny. |
| comparables_total | Yes | Wszystkie transakcje porównawcze serwisu. |
| comparables_omitted | Yes | Transakcji pominiętych przez limit. |
| comparables_returned | Yes | Transakcji na liście comparables. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/openWorld annotations: declares the estimate is approximate, explains estimated_value=null and the low_confidence<5 threshold with required hedging, enumerates result fields including truncated/omitted/hint, and warns that each call is a live service request that should not be batched across many points.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the one-line purpose and caveat, then return contract, then prerequisites; every paragraph carries actionable information. Minor redundancy from re-stating coordinate sourcing that the schema already explains, and the description is long for a 5-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite an output schema existing, the description supplies the handling rules an agent needs (null → read hint, low_confidence → hedge, truncated/omitted handling) plus cost awareness and the coordinate prerequisite. Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so lat, lng, limit and area_m2 are already documented; the description mostly repeats the coordinate-sourcing guidance already present in the schema descriptions. It adds the useful nuance that address does not determine position (lat/lng decide), but that too is mirrored in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Szacuje wartość mieszkania o danym metrażu w punkcie (lat, lng)') plus the data source (transakcje z Rejestru Cen Nieruchomości) and the caveat that it is a comparison, not an appraisal. It does not explicitly say how it differs from the aggregate-statistics siblings (get_market_statistics, get_transaction_statistics), so differentiation is inferable rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('Użyj, gdy użytkownik pyta, ile może być warte mieszkanie albo czy jego cena jest rynkowa'), a hard prerequisite (coordinates required, no geocoding), and routes the agent to search_locations or get_investment to obtain lat/lng. It also forbids batch use. It stops short of explicit when-not-to-use exclusions against the statistics siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_buildingBudynek z transakcjamiARead-only
Zwraca budynek z rejestru cen transakcyjnych (RCN): adres, współrzędne, średnie ceny podane przez serwis i lokale z transakcjami: datą, ceną, ceną za m², rynkiem, rodzajem i stronami. To ceny, za które lokale sprzedano, nie ceny ofertowe deweloperów. building_slug to ostatni człon adresu strony budynku z cenami transakcyjnymi na deweloperuch.pl, np. 23-marca-79c-sopot; gdy go nie znasz, poproś użytkownika o link do tej strony. building_url to ta strona: podaj ją jako link. Kolejność: lokale od tego z najnowszą transakcją, transakcje każdego lokalu od najstarszej. Transakcji o classification innym niż regular (udział, egzekucja, bonifikata…) nie uśredniaj ze zwykłymi: to nie zwykła sprzedaż po cenie rynkowej; liczy je non_regular_transactions.
Ograniczenia: tylko budynki z mieszkaniami, nie domy. Zwraca najwyżej limit lokali (domyślnie 10); truncated i units_omitted mówią, czy i ile pominięto; units_total i transactions_total liczą cały budynek. Najnowsze miesiące bywają niepełne (rejestr spływa z opóźnieniem). include_trend=true dodaje średnią cenę za m² transakcji w okolicy budynku (promień radius_km) w ostatnich 12 kwartałach; to jedno zapytanie do serwisu więcej.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Najwięcej lokali w wyniku (tych z najnowszymi transakcjami), domyślnie 10, najwyżej 50; 0 = tylko podsumowanie budynku. Ile pominięto, mówi units_omitted. Wynik ma ok. 200 znaków na transakcję; lokal może mieć kilka transakcji, więc zwykle wystarcza domyślny limit. | |
| building_slug | Yes | Slug budynku, np. 23-marca-79c-sopot, ze strony budynku albo z comparables w estimate_property_value. | |
| include_trend | No | true: dołącz średnią cenę za m² transakcji w okolicy budynku w ostatnich 12 kwartałach (jedno zapytanie więcej). |
Output Schema
| Name | Required | Description |
|---|---|---|
| lat | No | Współrzędne budynku (WGS84). |
| lng | No | Współrzędne budynku (WGS84). |
| city | Yes | Miasto budynku. |
| hint | No | Co zrobić dalej albo czego brakuje w wyniku, np. brak trendu w okolicy budynku. |
| name | No | Adres budynku wg rejestru cen; brak pola: rejestr nie podaje adresu (miejscowość w city). |
| units | Yes | Lokale od tego z najnowszą transakcją. |
| street | No | Ulica, tylko gdy inna niż name. |
| avg_price | No | Średnia cena transakcyjna lokalu w PLN, podana przez serwis. |
| city_slug | Yes | city_slug jak w search_locations. |
| truncated | Yes | true: lista units jest niepełna (units_omitted > 0). |
| avg_area_m2 | No | Średnia powierzchnia lokalu w m², podana przez serwis. |
| units_total | Yes | Wszystkie lokale budynku w rejestrze cen. |
| building_url | No | Strona budynku z cenami transakcyjnymi na deweloperuch.pl: podaj ją użytkownikowi jako link. |
| building_slug | Yes | Identyfikator do ponownego get_building. |
| units_omitted | Yes | Lokali pominiętych przez limit. |
| units_returned | Yes | Lokali na liście units. |
| avg_price_per_m2 | No | Średnia cena za m² w PLN, podana przez serwis. |
| transactions_total | Yes | Wszystkie transakcje lokali budynku. |
| neighbourhood_trend | No | Średnia cena za m² transakcji w okolicy budynku w kolejnych kwartałach; tylko przy include_trend=true. |
| last_transaction_date | No | Data najnowszej transakcji w budynku. |
| first_transaction_date | No | Data najstarszej transakcji w budynku. |
| non_regular_transactions | No | Transakcje z classification innym niż regular w całym budynku: liczba wg rodzaju (słowa jak w classification), np. {"share": 1}; brak pola: brak takich transakcji. To nie zwykła sprzedaż całego lokalu po cenie rynkowej: nie uśredniaj ich ze zwykłymi. Średnie avg_* serwisu prawdopodobnie ich nie obejmują (sprawdzone w jednym budynku). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld annotations, it discloses ordering rules (units by newest transaction, each unit's transactions oldest-first), how non-regular transaction classifications are excluded from averaging and counted separately, truncation semantics via truncated/units_omitted/units_total, incomplete recent registry months, and the extra backend call cost of include_trend. This is exactly the 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the purpose, then slug/URL, ordering, caveats, and limits in a logical sequence. It is dense and long, and the limit/truncation rules are partly duplicated in the schema, but nearly every sentence carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with an output schema, three parameters, and full schema coverage, the description covers everything an agent needs: what is returned, ordering, exclusion of non-market transactions, truncation flags, data-lag caveat, and the cost of the optional trend query.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds real meaning: building_slug is defined as the last URL segment of the building page with an example and a fallback instruction, and include_trend is explained as a nearby-area average over the last 12 quarters within radius_km. The limit behavior is also restated for truncation context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ("Zwraca budynek z rejestru cen transakcyjnych (RCN)") and enumerates the returned components: address, coordinates, average prices, and units with transactions. It explicitly differentiates itself from sibling offer tools with "To ceny, za które lokale sprzedano, nie ceny ofertowe deweloperów."
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete selection context: use only for apartment buildings, not houses ("tylko budynki z mieszkaniami, nie domy"), and instructs the agent to ask the user for the page link when building_slug is unknown. It does not, however, name a sibling alternative for the case where the building is unknown but a location search could help.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_developerProfil deweloperaARead-only
Zwraca profil dewelopera: nazwę, podsumowanie jego aktywnych ofert (summary), inwestycje z aktywnymi ofertami (najpierw te z największą liczbą aktywnych ofert) i jego miasta (cities, od miasta z największą liczbą aktywnych ofert). Nie podaje strony www dewelopera. Użyj, gdy pytanie dotyczy dewelopera: gdzie i ile buduje, w jakich cenach. developer_slug weź z search_developers (po nazwie) albo z pól developer_slug w search_offers, get_investment, get_offer i get_market_statistics (top_developers). developer_url i investment_url to strony na deweloperuch.pl: podawaj je użytkownikowi jako linki.
city zawęża summary i investments do jednego miasta (city_slug z search_locations albo z cities); domyślnie polska (cała Polska). cities obejmuje całą Polskę (gdy serwis nie podaje listy miast, tylko miasta inwestycji: wtedy hint). summary liczy narzędzie z inwestycji w zakresie city; summary.cities to liczba miast. Średnia cena oferty w jednym mieście: city=<city_slug>, pole summary.avg_price.
Ograniczenia: najwyżej limit inwestycji (domyślnie 20); o pominięciu mówią investments_omitted (ile), truncated i hint. Pojedynczych ofert tu nie ma: oferty inwestycji daje get_investment.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | city_slug miasta z search_locations albo z cities wyniku get_developer (np. krakow), albo polska (domyślnie: cała Polska). | polska |
| limit | No | Najwięcej inwestycji w wyniku (najpierw te z największą liczbą aktywnych ofert), 1–100, domyślnie 20. Inwestycja to 350–400 znaków wyniku; zwykle wystarcza domyślne 20. | |
| developer_slug | Yes | developer_slug z search_developers (po nazwie) albo z pól developer_slug w search_offers, get_investment, get_offer, get_market_statistics (top_developers), np. atal. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | |
| cities | Yes | Wszystkie miasta dewelopera w Polsce, niezależnie od argumentu city (także przy city=warszawa), od miasta z największą liczbą aktywnych ofert. |
| summary | Yes | |
| city_slug | Yes | Zakres summary i investments: miasto albo polska. |
| developer | Yes | |
| truncated | Yes | true: lista investments jest niepełna. |
| investments | Yes | |
| developer_url | No | Profil dewelopera na deweloperuch.pl: podaj go użytkownikowi jako link. |
| investments_total | Yes | Wszystkie inwestycje z aktywnymi ofertami. |
| investments_omitted | Yes | Inwestycji pominiętych przez limit. |
| investments_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/openWorldHint already covering the safety profile, the description still adds substantial behavior: default scope is all of Poland, city narrows both summary and investments, cities is always Poland-wide with a hint when the site provides no city list, summary is computed by the tool from investments in scope, summary.cities is a count, and truncation is signalled via investments_omitted/truncated/hint. It even specifies output guidance (developer_url and investment_url should be surfaced to the user as links).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then usage, then parameter scope, then limits — a sensible order with no filler sentences. It is dense and runs long, and the developer_slug provenance restates the schema description, so some trimming is possible, but every remaining block carries operational information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter read tool with an output schema, the definition covers scope defaults, aggregation semantics, truncation signalling, and cross-tool slug sourcing. An agent has everything needed to call it correctly and interpret partial results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description goes further by explaining what city actually changes (aggregation scope for summary/investments, default 'polska'), where city_slug values come from, and the practical consequence of limit (at most N investments, omission flags). The developer_slug sourcing is largely repeated from the schema, which keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete verb+resource ('Zwraca profil dewelopera') and enumerates exactly what comes back: name, offer summary, investments with active offers, and cities. It also explicitly bounds the tool ('Nie podaje strony www dewelopera') and distinguishes it from get_investment for individual offers, so an agent can separate it from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States the triggering question shape ('gdy pytanie dotyczy dewelopera: gdzie i ile buduje, w jakich cenach'), tells where to source developer_slug (search_developers, or developer_slug fields in search_offers, get_investment, get_offer, get_market_statistics), and names the exclusion case pointing to get_investment for individual offers.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_government_statisticsStatystyki GUS, NBP i EurostatuARead-only
Zwraca oficjalne statystyki GUS, NBP i Eurostatu (demografia Polski) jako szeregi czasowe dla Polski, agregatu miast albo miasta na prawach powiatu: mieszkania oddane i rozpoczęte, średnią powierzchnię mieszkań deweloperskich, ceny m² wg NBP, bezrobocie, wynagrodzenia, demografię i ludność (parametr dataset). Ofert mieszkań tu nie ma (search_offers), ceny z rejestru RCN daje get_transaction_statistics, a porównanie wielu miast w jednym okresie rank_locations z indicator.
Zwraca periods (od najstarszego) i series (series_id, label, unit, values wyrównane z periods; null = brak danych) oraz frequency, source, total, returned, truncated, available_from, note i stats_url (sekcja strony na deweloperuch.pl: podaj ją użytkownikowi jako link).
Ograniczenia: domyślnie ostatnie 12 okresów; truncated=true: są starsze (zwiększ periods, najwyżej 120). nbp_prices: tylko 3 agregaty i część dużych miast (np. warszawa, krakow), nie polska. Nie każdy zestaw jest dostępny dla każdej lokalizacji (błąd wskaże, co podać); dane GUS i NBP są publikowane z opóźnieniem: ostatni okres bywa sprzed kilku tygodni lub miesięcy, dla demografii Polski nawet roku. Przeczytaj note: ostatni okres bywa niepełny.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset | Yes | dwellings_quarterly: mieszkania oddane do użytkowania i rozpoczęte (razem, wg form budownictwa, na wynajem), kwartalnie; dwellings_monthly: to samo miesięcznie; average_area: średnia powierzchnia mieszkania oddanego przez deweloperów (m², rocznie); demography: urodzenia żywe, zgony, przyrost naturalny (dla Polski miesięcznie wg Eurostatu, dla miast rocznie wg GUS); population: ludność, kobiety i mężczyźni (rocznie); unemployment: stopa bezrobocia rejestrowanego (%, miesięcznie); wages: przeciętne miesięczne wynagrodzenie brutto w PLN (dla Polski miesięcznie, dla miast rocznie, czasem z relacją do średniej krajowej); nbp_prices: średnie ceny m² wg NBP, rynek pierwotny i wtórny, ofertowe i transakcyjne (PLN/m², kwartalnie). Częstotliwość zwraca pole frequency. Agregat 7-miast nie ma wages ani unemployment (są dla miast i polska). | |
| periods | No | Ile ostatnich okresów zwrócić (lat, kwartałów albo miesięcy), 1–120, domyślnie 12. Najszerszy zestaw (mieszkania, 15 szeregów) przy 120 miesiącach to ok. 10 tys. znaków. Dla trendów bierz dane roczne/kwartalne; miesięczne 120 okresów tylko, gdy użytkownik o to prosi. | |
| location | Yes | polska (cała Polska), agregat 7-miast, 10-miast albo 6-miast-bez-warszawy, albo jedno z 66 miast na prawach powiatu: nazwa małymi literami bez polskich znaków, z myślnikami zamiast spacji, np. warszawa, krakow, lodz, bielsko-biala, zielona-gora, jastrzebie-zdroj. Dane są tylko dla 66 miast na prawach powiatu, a nie dla dzielnic i mniejszych miejscowości. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Co zrobić dalej, gdy wynik jest obcięty. |
| note | No | Uwaga do danych, np. ostatni kwartał obejmuje tylko część miesięcy. |
| title | Yes | |
| total | Yes | Wszystkie okresy, które serwis ma dla tego zestawu. |
| series | Yes | |
| source | Yes | Źródło danych: GUS, NBP albo Eurostat. |
| dataset | Yes | |
| periods | Yes | Okresy od najstarszego: 2025 (rok), 2025-Q3 (kwartał) albo 2025-08 (miesiąc). |
| returned | Yes | Okresy w wyniku: ostatnie z nich. |
| frequency | Yes | year (lata), quarter (kwartały) albo month (miesiące). |
| stats_url | No | Link do sekcji z tymi danymi w serwisie: podaj go użytkownikowi. |
| truncated | Yes | true: są starsze okresy niż pokazane; co dalej, mówi hint. |
| location_name | Yes | |
| location_slug | Yes | |
| available_from | Yes | Najstarszy okres, jaki ma serwis. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint/openWorldHint it discloses concrete behavior: default of 12 periods, truncated=true signaling older data available with periods up to 120, a size estimate (~10k characters), and publication lag (last period may be weeks/months old, up to a year for Polish demography) plus an incomplete-last-period caveat via 'note'. It also flags the nbp_prices geographic limitation and that errors indicate what to supply — none of which the annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight paragraphs with clear roles: what it returns, what it excludes, and limitations — front-loaded with the resource statement. It loses a point because the field list ('periods, series (series_id, label, unit, values...), frequency, source, total, returned, truncated, available_from, note, stats_url') restates an output schema that already exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only statistics tool with 3 parameters, an enum, and an output schema, an agent has everything needed: dataset semantics, location format rules (lowercase, no diacritics, hyphens, 66 powiat cities only), period limits, data lag expectations, and the instruction to surface stats_url as a link. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds cross-parameter meaning the schema only partly captures, namely that dataset availability varies by location and that an error will name the correct value. The dataset and periods semantics (enum meanings, 1–120 range, size tradeoff) largely duplicate the schema's own parameter descriptions, so it stops short of a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific verb+resource ('Zwraca oficjalne statystyki GUS, NBP i Eurostatu') and enumerates the exact content (mieszkania oddane i rozpoczęte, ceny m² wg NBP, bezrobocie, wynagrodzenia, demografia), plus the three location granularities. It explicitly rules out sibling concerns: offers → search_offers, RCN transaction prices → get_transaction_statistics, multi-city comparison → rank_locations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not guidance with named alternatives and the condition that selects each one ('Ofert mieszkań tu nie ma (search_offers)... ceny z rejestru RCN daje get_transaction_statistics... porównanie wielu miast... rank_locations'). It also states dataset-specific usage limits (nbp_prices only 3 aggregates and some large cities, not 'polska') and warns that not every dataset exists for every location, with an error message as the fallback.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_investmentInwestycja z ofertamiARead-only
Zwraca inwestycję (projekt deweloperski): miasto, ulicę, współrzędne, dewelopera, średnie ceny aktywnych ofert, liczbę ofert i listę ofert (najpierw aktywne, potem archiwalne). Użyj, gdy chcesz zobaczyć mieszkania jednego projektu. investment_slug daje search_investments, search_offers albo get_developer. investment_url i developer_url to strony inwestycji i dewelopera na deweloperuch.pl: podawaj je użytkownikowi jako linki.
Ograniczenia: zwraca najwyżej limit ofert (domyślnie 20); offers_returned mówi, ile ich jest na liście, truncated i offers_omitted, czy i ile pominięto. offers_total to liczba z serwisu, a pominięte oferty liczy offers_omitted. Przy dużej inwestycji nie zwiększaj limitu bez potrzeby; offers_omitted > 0 znaczy, że lista jest niepełna. include_history=true dodaje każdej zwróconej ofercie price_history (zdarzenia ceny od najstarszego): ok. 150 znaków więcej na ofertę, czyli przy limicie 20 do ok. 10 tys. znaków zamiast ok. 6 tys. Zmianę od pierwszej ceny ma każda oferta także bez historii (price_change_since_start), więc historię dodawaj, gdy liczy się przebieg ceny. Dla jednej oferty lepiej użyć get_offer.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Najwięcej ofert w wyniku (najpierw aktywne), domyślnie 20, 0 = tylko podsumowanie inwestycji. Ile pominięto, mówi offers_omitted. Każda oferta to ok. 300 znaków wyniku, z historią ceny ok. 450 (zdarzenie to ok. 55 znaków). Maksimum 200 daje ok. 60 tys. znaków; zwykle wystarcza domyślne 20. | |
| include_history | No | true: dołącz price_history każdej zwróconej oferty (ok. 150 znaków więcej na ofertę). | |
| investment_slug | Yes | investment_slug z search_investments, search_offers albo get_developer, np. smolna. |
Output Schema
| Name | Required | Description |
|---|---|---|
| lat | No | |
| lng | No | |
| city | Yes | |
| name | Yes | |
| offers | Yes | |
| status | Yes | active (aktualna) albo archived (wycofana). |
| street | No | |
| currency | No | |
| avg_price | No | Średnia cena aktywnych ofert w PLN. |
| city_slug | Yes | |
| developer | Yes | |
| truncated | Yes | true: lista offers jest niepełna (offers_omitted > 0). |
| avg_area_m2 | No | |
| offers_total | No | Wszystkie oferty inwestycji wg serwisu, także archiwalne; lista offers jest ucięta przez limit. |
| developer_url | No | Profil dewelopera na deweloperuch.pl: podaj go użytkownikowi jako link. |
| offers_active | No | |
| investment_url | No | Strona inwestycji na deweloperuch.pl: podaj ją użytkownikowi jako link. |
| offers_omitted | Yes | Ofert pominiętych przez limit. |
| investment_slug | Yes | |
| offers_returned | Yes | Ofert na liście offers. |
| avg_price_per_m2 | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnly/openWorld annotations, it discloses pagination semantics (offers_returned, truncated, offers_omitted, offers_total), the meaning of a non-zero offers_omitted as an incomplete list, and the payload cost of include_history (~10k vs ~6k characters at limit 20). It even notes that price_change_since_start is available without history, which is exactly the trade-off an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the mapping of slug to source tools, then a clearly separated 'Ograniczenia' block for limits and cost. It is somewhat long and repeats offer/character-count figures that also appear in the limit schema description, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-parameter read tool with an output schema, the description covers everything an agent needs: how to obtain the slug, how to surface the returned URLs to the user, how truncation is signalled, and when to escalate to get_offer. Nothing material is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 adds decision-relevant meaning: what limit=0 means, why not to raise the limit, and when include_history is worth its ~150-character-per-offer cost. It largely restates rather than extending the schema's own parameter text, which caps it below 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource ('Zwraca inwestycję (projekt deweloperski)') and enumerates exactly what comes back: city, street, coordinates, developer, average prices of active offers, offer counts, and an offer list ordered active-first. It also distinguishes itself from a sibling by pointing single-offer lookups to get_offer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states explicitly when to use it ('Użyj, gdy chcesz zobaczyć mieszkania jednego projektu'), where the required investment_slug comes from (search_investments, search_offers, get_developer), and redirects to get_offer when only one listing is needed. Both the positive trigger and the alternative path are present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_market_statisticsStatystyki rynku miastaARead-only
Zwraca statystyki rynku ofert deweloperskich w jednym mieście: liczbę ofert, inwestycji i deweloperów, rozkład cen (PLN), cen za m² (PLN/m²) i metraży (m²) jako min, p25, median, p75 i max oraz największych deweloperów wg liczby ofert (developer_name, developer_slug, offers, investments, median_price_per_m2, developer_url). Opcjonalnie tylko oferty z zakresu ceny i metrażu. Użyj, gdy pytanie dotyczy rynku miasta (typowe ceny, kto ma najwięcej ofert), a nie konkretnych mieszkań (search_offers; inwestycje dewelopera daje get_developer).
Ograniczenia: tylko aktywne oferty (bez archiwalnych) i tylko jedno miasto (city_slug z search_locations; polska nie działa). Liczby to stan na dzień z pola wyniku as_of i mogą się nieco różnić od total w search_offers. Pojedynczych ofert tu nie ma: list_url to lista tych ofert na deweloperuch.pl z tymi samymi filtrami, a developer_url profil dewelopera: podawaj je użytkownikowi jako linki.
| Name | Required | Description | Default |
|---|---|---|---|
| city | Yes | city_slug jednego miasta z search_locations, np. krakow (nie polska). | |
| area_max | No | Największy metraż w m². | |
| area_min | No | Najmniejszy metraż w m². | |
| price_max | No | Najwyższa cena oferty w PLN. | |
| price_min | No | Najniższa cena oferty w PLN. | |
| top_developers | No | Ilu największych deweloperów pokazać, 1–30, domyślnie 10. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | |
| as_of | No | Dzień, na który serwis podał oferty (może być wczorajszy): podawaj go przy liczbach. |
| price | No | Ceny w PLN: min, kwartyle, mediana, max. |
| offers | Yes | Pasujące aktywne oferty. |
| area_m2 | No | Metraże w m². |
| list_url | No | Lista tych ofert na deweloperuch.pl (te same filtry ceny i metrażu): podaj ją użytkownikowi jako link. |
| city_slug | Yes | |
| truncated | Yes | true: deweloperów jest więcej niż w top_developers. |
| developers | Yes | Wszyscy deweloperzy z pasującymi ofertami. |
| investments | Yes | Inwestycje z pasującymi ofertami. |
| price_per_m2 | No | Ceny za m² w PLN. |
| top_developers | Yes | Deweloperzy z największą liczbą pasujących ofert, malejąco. |
| developers_omitted | Yes | |
| developers_returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint; the description adds substantially more: only active (non-archived) offers are counted, only one city per call, "polska" fails, figures are as-of the as_of result field and may diverge from search_offers totals, and individual offers are absent so list_url/developer_url must be surfaced to the user as links. These are real behavioral traits an annotation cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and outputs, then usage routing, then caveats — a sensible ordering. It is dense and the enumeration of every developer field is somewhat verbose, and "Opcjonalnie tylko oferty z zakresu ceny i metrażu" partly restates optional schema defaults, but no sentence is pure filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only statistics tool with 6 params, full schema coverage and an output schema, the description covers scope, freshness, aggregation caveats, and the follow-up links an agent must present. Nothing needed to call it correctly — or to interpret the numbers — is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema: city must be a city_slug obtained from search_locations and must not be "polska", and the price/area parameters restrict which offers the statistics are computed over rather than just filtering output. The top_developers parameter's effect is only implied by the mention of "największych deweloperów wg liczby ofert".
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Zwraca statystyki rynku ofert deweloperskich w jednym mieście") and enumerates exactly what is returned: offer/investment/developer counts, price and price-per-m² and area distributions as min/p25/median/p75/max, and top developers by offer count. It then explicitly contrasts itself with search_offers (individual listings) and get_developer (a developer's investments), so the agent can distinguish it from siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit when-to-use rule — "Użyj, gdy pytanie dotyczy rynku miasta (typowe ceny, kto ma najwięcej ofert)" — together with the when-not condition ("a nie konkretnych mieszkań") and the exact alternative to route to (search_offers, get_developer). The single-city constraint and the warning that "polska" is not a valid city_slug further steer correct invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_offerOferta z historią cenyARead-only
Zwraca jedną ofertę z pełną historią ceny, inwestycją i deweloperem. Użyj, gdy chcesz zobaczyć, jak zmieniała się cena mieszkania. Wymaga offer_id i investment_slug (oba podaje search_offers albo get_investment): samo offer_id nie wystarcza.
Zwraca cenę, metraż, cenę za m², status (active albo archived), zmianę od pierwszej ceny, daty, price_history (date, kind: offer, archived albo restored, price) i price_flags. investment_url i developer_url to strony inwestycji i dewelopera na deweloperuch.pl: podawaj je użytkownikowi jako linki. Do listy ofert jednej inwestycji użyj get_investment.
price_flags (na dziś; ceny z offer i restored, wycofanie przerywa cenę; oferta archiwalna do dnia wycofania): lowest_price_30d i lowest_price_90d to najniższa cena obowiązująca w ostatnich 30 i 90 dniach, także ta sprzed okna; price_changes to liczba zmian ceny; largest_drop_pct i largest_rise_pct to największa pojedyncza obniżka i podwyżka w % poprzedniej ceny; suspicious_reduction=true, gdy ostatnia obniżka przyszła do 30 dni po podwyżce, a nowa cena nie jest niższa od najniższej z 30 dni przed nią („promocja” po podwyżce).
| Name | Required | Description | Default |
|---|---|---|---|
| offer_id | Yes | offer_id z search_offers albo get_investment. | |
| investment_slug | Yes | investment_slug inwestycji tej oferty, np. smolna (z search_investments, search_offers albo get_developer). |
Output Schema
| Name | Required | Description |
|---|---|---|
| city | Yes | |
| name | Yes | |
| price | No | Cena ofertowa w PLN (nie transakcyjna). |
| status | Yes | active (aktualna) albo archived (wycofana). |
| area_m2 | No | Metraż w m². |
| currency | No | |
| offer_id | Yes | |
| city_slug | Yes | |
| developer | Yes | |
| price_flags | No | Wnioski z historii ceny na dziś: ceny z offer i restored; wycofanie przerywa obowiązującą cenę. |
| price_per_m2 | No | Cena za m² w PLN (price / area_m2). |
| creation_date | No | |
| developer_url | No | Profil dewelopera na deweloperuch.pl: podaj go użytkownikowi jako link. |
| price_history | Yes | |
| investment_url | No | Strona inwestycji na deweloperuch.pl: podaj ją użytkownikowi jako link. |
| investment_name | Yes | |
| investment_slug | Yes | |
| last_event_date | No | |
| last_change_date | No | |
| price_change_since_start | No | Zmiana ceny od pierwszej zaobserwowanej, w PLN (ujemna = tańsza). |
| price_change_since_start_pct | No | Zmiana ceny od pierwszej zaobserwowanej, w procentach (ujemna = tańsza). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds real behavioral context beyond that: the two-parameter prerequisite, the fields returned, the semantic meaning of price_flags, and the instruction to surface investment_url/developer_url as links. It does not cover pagination or error behavior, so a 4 rather than 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded correctly: purpose, then when-to-use, then prerequisites, then return contents. The price_flags explanation is lengthy and partly overlaps what the output schema already carries, but it does encode semantics (e.g. the suspicious_reduction rule) that are not self-evident. Slightly verbose but each block earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool whose complexity lies in price-history interpretation, the description supplies the prerequisite, the alternative tool, the return shape, and the meaning of every flag. Even though an output schema exists, the semantic definitions of lowest_price_30d/90d and suspicious_reduction are necessary context an agent cannot infer from structure alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters and their sources. The description adds only the constraint that offer_id alone is not enough, which is a marginal increment over the schema's own parameter descriptions. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: it returns one offer together with its full price history, investment, and developer. It explicitly distinguishes itself from the sibling get_investment by noting that listing offers for one investment is a different tool. An agent can tell exactly what it retrieves 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit use case ("Użyj, gdy chcesz zobaczyć, jak zmieniała się cena mieszkania"), names the alternative for a related task (get_investment for offer lists), and states a hard prerequisite: both offer_id and investment_slug are required, with offer_id alone insufficient. Nothing about when/when-not is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_transaction_statisticsCeny transakcyjne w czasieARead-only
Zwraca ceny transakcyjne mieszkań w mieście z Rejestru Cen Nieruchomości (RCN) od 2017 r., w kolejnych miesiącach albo kwartałach: liczbę transakcji i ceny za m². To ceny faktycznych sprzedaży, a nie ceny ofertowe deweloperów (search_offers, get_market_statistics) ani oficjalne ceny NBP (get_government_statistics).
granularity=month (domyślnie): tylko rynek wtórny; mediana i średnia ceny za m², mediana metrażu i mediana ceny mieszkania. granularity=quarter: tylko mediana ceny za m² i liczba transakcji; rynek nieokreślony. Miesiące i kwartały to różne statystyki: nie łącz ich w jeden wykres ani szereg.
Ograniczenia: tylko mieszkania i całe miasta (city_slug z search_locations; bez dzielnic, ulic, agregatów (np. 7-miast) i całej Polski). Domyślnie ostatnie 12 okresów; truncated=true znaczy, że są starsze (zwiększ periods, najwyżej 60; całą historię od 2017 r. daje tylko quarter). Dane RCN spływają z opóźnieniem, więc najnowsze okresy są niepełne: okres z incomplete=true pomiń, nie podawaj jego cen jako trendu. Okres bez transakcji nie ma cen. Trend kończ na last_complete_period (jego dane też mogą się zmienić); brak pola (za mało transakcji): czytaj hint.
| Name | Required | Description | Default |
|---|---|---|---|
| city | Yes | city_slug miasta z search_locations, np. warszawa, krakow, gdansk (małe litery bez polskich znaków). Statystyki są dla całych miast; dzielnice, ulice, agregaty miast (np. 7-miast) i cała Polska (polska) nie są obsługiwane. | |
| periods | No | Ile ostatnich okresów (miesięcy albo kwartałów) zwrócić, 1–60, domyślnie 12. 60 miesięcy to ok. 9 tys. znaków; dla trendu wieloletniego wybierz quarter zamiast wielu miesięcy. | |
| granularity | No | month (domyślnie): miesiące, tylko rynek wtórny, z medianą i średnią ceny za m², medianą metrażu i medianą ceny mieszkania; quarter: kwartały, tylko mediana ceny za m² i liczba transakcji (rynek nieokreślony), za to cała historia od 2017 r. w jednym wywołaniu (periods=60). | month |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Co zrobić dalej: gdy wynik jest obcięty, ma okresy incomplete albo za mało transakcji, by je ocenić. |
| note | Yes | Uwaga do danych: najnowsze okresy są niepełne. |
| total | Yes | Wszystkie okresy, które serwis ma dla miasta. |
| periods | Yes | Okresy od najstarszego; okres bez transakcji nie ma cen ani metrażu. |
| returned | Yes | Okresy w wyniku: ostatnie z nich. |
| city_slug | Yes | |
| stats_url | No | Strona statystyk transakcji na deweloperuch.pl dla ludzi: podaj ją użytkownikowi jako link. |
| truncated | Yes | true: są starsze okresy niż pokazane; co dalej, mówi hint. |
| granularity | Yes | month (miesiące) albo quarter (kwartały). |
| available_from | Yes | Najstarszy okres, jaki ma serwis. |
| last_complete_period | No | Najnowszy okres ze zwykłą liczbą transakcji (nie incomplete), pokazany lub nie; na nim kończ trend, choć jego dane mogą się jeszcze zmienić. Brak pola: za krótka historia albo za mało transakcji, by to ocenić. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld annotations it discloses non-obvious behaviour: default of 12 periods, truncated=true meaning older data exists, the 60-period ceiling, publication lag causing incomplete periods, periods with no transactions, and that last_complete_period is still provisional with a hint field for suppressed values. That is substantive operational context, though the response envelope itself is left to the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structure is deliberate: purpose and sibling disambiguation first, then granularity semantics, then constraints and data-quality caveats. It is dense and the long run-on sentence about truncated, incomplete and last_complete_period packs several distinct rules together, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only three-parameter statistics tool with a full output schema, the description covers everything an agent needs: scope limits, mode trade-offs, pagination ceiling, data-lag handling and how to treat incomplete or empty periods. Return-value detail is correctly delegated to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema descriptions already define the month/quarter trade-offs, the 1–60 range and the city_slug format, so the description largely restates rather than adds. The only marginal additions are the pairing of truncated with periods and the note that periods=60 gives full history only for quarter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource (transaction prices for flats in a city from RCN since 2017) plus the measures returned, and explicitly separates this tool from three named siblings: search_offers, get_market_statistics and get_government_statistics. An agent can pick this tool over its neighbours without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use each mode (month = secondary market with full medians; quarter = long history but fewer measures) and explicitly warns not to merge the two series. Hard exclusions are spelled out: flats only, whole cities only, no districts, streets, aggregates or Poland-wide data.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rank_locationsRanking miast i powiatówARead-only
Porównanie wielu miejsc w jednym okresie; nie zwraca szeregu czasowego. Dwa tryby: (1) bez indicator: ranking miejscowości (level=city) albo powiatów (level=powiat) wg transakcji z RCN (liczba, cena za m²); (2) z indicator: ranking 66 miast na prawach powiatu wg wskaźnika GUS lub NBP. Trend jednego miasta w czasie: get_transaction_statistics (RCN) albo get_government_statistics (GUS, NBP). Bez indicator to ceny transakcyjne z RCN, nie ofertowe; nbp_price_per_m2 to oficjalna cena NBP, nie RCN.
Zwraca total, returned, truncated, hint i items. Transakcje: min_transactions (zastosowany próg), items (name, city_slug albo powiat_id, transaction_count, price_per_m2, area_m2, price); dla city ranking_url (link dla użytkownika); dla powiat market i okres 12 miesięcy period_start–period_end. Wskaźnik: indicator, unit, period, items (name, city_slug, value, stats_url: link dla użytkownika).
Ograniczenia: serwis nie mówi, czy ceny i metraż to średnie, czy mediany. Okresu miejscowości serwis nie podaje; nie porównuj liczb transakcji miejscowości i powiatów. Sortowanie po cenie domyślnie pomija miejsca poniżej 20 transakcji (cena bywa przypadkowa); min_transactions=0 pokazuje wszystkie.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | transactions_desc: najwięcej transakcji (domyślnie bez indicator); price_per_m2_desc, price_per_m2_asc: najwyższa, najniższa cena za m² (miejsca bez ceny na końcu); value_desc (domyślnie z indicator), value_asc: najwyższa, najniższa wartość wskaźnika, tylko z indicator. | |
| level | No | city: miejscowości (miasta, także małe miasteczka i wsie), domyślnie; powiat: powiaty, tylko transakcje (market); powiaty nie mają city_slug ani ranking_url i nie ma ich w search_locations. Z indicator tylko city. | city |
| limit | No | Ile pierwszych pozycji rankingu zwrócić, 1–100, domyślnie 20. Pozycja to ok. 120 znaków wyniku. Dla pełnych list zawężaj min_transactions, nie podnoś limitu bez potrzeby. | |
| market | No | Tylko level=powiat. secondary: rynek wtórny (domyślnie); primary: pierwotny; all: oba rynki w zestawieniu serwisu (jego liczba transakcji nie zawsze równa się secondary + primary). Powiaty bez danych dla rynku są pominięte (hint). | |
| indicator | No | Ranking 66 miast na prawach powiatu według wskaźnika zamiast transakcji (bez level=powiat, min_transactions i market): unemployment_rate: stopa bezrobocia rejestrowanego (%) w miesiącu; average_wage: przeciętne miesięczne wynagrodzenie brutto (PLN), średnia za rok period (jak dataset=wages w get_government_statistics); dwellings_completed, dwellings_started: mieszkania oddane, rozpoczęte w 12 miesiącach do miesiąca period; average_dwelling_area: powierzchnia mieszkania (m²) podana przez serwis za okres period; nie porównuj jej z average_area z get_government_statistics (inna definicja); natural_increase: przyrost naturalny (osoby) w roku; nbp_price_per_m2: cena transakcyjna rynku wtórnego wg NBP (PLN/m²) w kwartale, tylko 17 miast. Miasta bez wartości są pominięte (hint). | |
| min_transactions | No | Brak = próg domyślny: 20 przy sortowaniu po cenie, 0 przy transactions_desc. 0 = wszystkie miejsca. Pomija miejsca z mniejszą liczbą transakcji; np. 50 daje stabilniejsze ceny. Nie działa z indicator. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | Co zrobić, gdy wynik jest obcięty albo pusty, oraz co pominięto: małe miejsca przy sortowaniu po cenie (domyślny próg), powiaty bez danych dla market, miasta bez wskaźnika. |
| sort | Yes | Kolejność rankingu, jak w argumencie sort. |
| unit | No | Jednostka value: %, PLN/mies., mieszkania (suma 12 miesięcy), m², osoby albo PLN/m². |
| items | Yes | |
| level | Yes | city (miejscowości) albo powiat (powiaty). |
| total | Yes | Wszystkie miejsca spełniające kryteria: z co najmniej min_transactions transakcji, z danymi dla market albo z wartością wskaźnika. |
| market | No | Rynek rankingu powiatów: secondary, primary albo all. |
| period | No | Okres wartości wskaźnika: miesiąc (RRRR-MM), kwartał (RRRR-Qn) albo rok (RRRR); dla dwellings_completed i dwellings_started ostatni miesiąc okna 12 miesięcy. |
| returned | Yes | Pozycje w items: pierwsze z rankingu. |
| indicator | No | Wskaźnik rankingu, jak w argumencie. |
| truncated | Yes | true: miejsc jest więcej, niż pokazano; co dalej, mówi hint. |
| period_end | No | Ostatni miesiąc okresu transakcji powiatów (RRRR-MM), wliczony w okres. |
| ranking_url | No | Strona rankingu miast na deweloperuch.pl (tylko level=city bez indicator): podaj ją użytkownikowi jako link. |
| period_start | No | Pierwszy dzień okresu transakcji powiatów (RRRR-MM-01). |
| min_transactions | No | Zastosowany próg: min_transactions z argumentu, a bez niego domyślny: 20 przy sortowaniu po cenie, 0 przy transactions_desc (0 = wszystkie miejsca). Brak przy indicator. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond readOnlyHint/openWorldHint by disclosing data-quality caveats an agent could not infer: the service doesn't say whether prices/area are mean or median, city period is not reported, price sorting silently drops places below 20 transactions unless min_transactions=0, market=all totals may not equal secondary+primary, and nbp_price_per_m2 covers only 17 cities. It also explains that omitted places are surfaced via 'hint', which directly affects how results should be interpreted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the two modes, then constraints — good ordering. It is long, and the paragraph enumerating return fields overlaps with the existing output schema, which is the one place wording does not fully earn its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter, two-mode ranking tool with heavy cross-tool definitional traps, the description covers mode selection, incompatibilities, default thresholds, data caveats and result interpretation. Combined with the output schema, an agent has everything needed to call it correctly and to avoid the documented pitfalls.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so this is above baseline: the description adds cross-field constraints the schema only partially implies (indicator excludes level=powiat, min_transactions and market), a usage tip for limit ('zawężaj min_transactions, nie podnoś limitu'), and a definitional warning that average_dwelling_area is not comparable to average_area from get_government_statistics. Slightly redundant in restating enum semantics already documented per-parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names a specific verb+resource ('Porównanie wielu miejsc w jednym okresie') and immediately states the negative scope ('nie zwraca szeregu czasowego'), then splits it into two explicit modes (with/without indicator). It names the sibling tools that cover the excluded case, so an agent can route without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use routing: 'Trend jednego miasta w czasie: get_transaction_statistics (RCN) albo get_government_statistics (GUS, NBP)'. Mode selection conditions are stated (level=city vs powiat without indicator, indicator forces city-only), and it warns against an invalid comparison ('nie porównuj liczb transakcji miejscowości i powiatów').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_developersSzukaj deweloperówARead-only
Znajduje deweloperów (rynek pierwotny) po fragmencie nazwy, np. atal albo dom development. Użyj, żeby zamienić nazwę dewelopera na developer_slug, którego wymaga get_developer (profil dewelopera; domyślnie dla całej Polski, city=polska). Nie zwraca ofert ani cen.
Zwraca items (developer_slug, name, offer_count, czyli liczbę ofert dewelopera wg serwisu, i developer_url, czyli profil na deweloperuch.pl: podawaj go użytkownikowi jako link) oraz total, returned, truncated i hint. truncated=true znaczy, że pasujących deweloperów jest więcej niż pokazano: doprecyzuj nazwę albo zwiększ limit (najwyżej 20). total jest null, gdy wiadomo tylko, że jest ich więcej.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Fragment nazwy dewelopera, 2–100 znaków, np. atal, Dom Development. | |
| limit | No | Najwięcej deweloperów w wyniku, domyślnie 5, najwyżej 20. Każdy to ok. 150 znaków wyniku. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | |
| items | Yes | |
| total | Yes | Wszyscy pasujący deweloperzy; null, gdy wiadomo tylko, że jest ich więcej. |
| returned | Yes | |
| truncated | Yes | true: pasujących deweloperów jest więcej niż pokazano; co dalej, mówi hint. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered; the description adds genuinely useful behavior: the name-to-slug conversion role, the truncation contract (truncated=true means more matches exist, refine or raise limit to max 20), and the total=null edge case. It does restate some return-field structure that the output schema likely covers, which keeps it off a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core purpose before the routing rationale, then the return/truncation contract. Dense but every sentence carries information; the field-by-field enumeration of items is the only mild over-explanation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema, full parameter descriptions, and annotations present, the description only needs to add the lookup role and truncation handling, both of which it covers. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents both 'name' (fragment, 2–100 chars, examples) and 'limit' (default 5, max 20). The description largely repeats those facts, though it does add the framing that 'name' is a lookup key for slug resolution. Baseline 3 is appropriate when the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Znajduje deweloperów ... po fragmencie nazwy') and scopes it to the primary market, then explicitly excludes adjacent data ('Nie zwraca ofert ani cen'). It distinguishes itself from siblings by naming the downstream tool it feeds, get_developer.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('Użyj, żeby zamienić nazwę dewelopera na developer_slug, którego wymaga get_developer'), names the alternative/next step, and states a when-not ('Nie zwraca ofert ani cen'). An agent knows exactly when to pick this over search_offers or get_developer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_investmentsSzukaj inwestycjiARead-only
Wyszukuje inwestycje (projekty deweloperskie, rynek pierwotny). Dwa tryby: city (pełne dane) albo samo name (cała Polska; tylko investment_slug, name i offers_active, w kolejności serwisu). Użyj, gdy pytanie dotyczy projektów, a nie pojedynczych mieszkań: np. najtańsze za m² w mieście, inwestycje jednego dewelopera, slug inwestycji po nazwie.
Z city zwraca inwestycje, które serwis pokazuje na mapie miasta (z aktywnymi ofertami; bez nich mogą nie być na liście): investment_slug, name, city_slug, ulica, status, offers_active, offers_total, średnie (avg_price, avg_area_m2, avg_price_per_m2; tylko aktywne oferty, wg serwisu), developer_slug, developer_name, investment_url i developer_url. name i developer_slug zawężają listę, sort ją porządkuje (domyślnie najwięcej aktywnych ofert); pozycje bez średniej są na końcu. Oferty i szczegóły inwestycji daje get_investment (investment_slug). Linki podawaj użytkownikowi.
Ograniczenia: najwyżej limit pozycji; total, returned, truncated i hint mówią, ile pominięto i co zawęzić. Nie filtruje po cenie ani metrażu (do tego search_offers); city=polska nie działa.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | city_slug miasta z search_locations, np. warszawa, sopot (nie polska). | |
| name | No | Fragment nazwy inwestycji, 2–100 znaków, np. Kolibki. Z city wielkość liter i polskie znaki nie mają znaczenia; bez city szuka serwis w całej Polsce. | |
| sort | No | Tylko z city. active_offers: najwięcej aktywnych ofert (domyślnie); price_per_m2_asc, price_per_m2_desc: średnia cena za m²; price_asc, price_desc: średnia cena; name: alfabetycznie. Bez średniej na końcu. | |
| limit | No | Najwięcej inwestycji w wyniku, 1–30, domyślnie 10. Pozycja z city to ok. 550–750 znaków wyniku (z linkami), więc 30 daje najwyżej ok. 23 tys.; zwykle wystarcza 10. | |
| developer_slug | No | developer_slug z search_developers (po nazwie) albo z pól developer_slug w search_offers, get_investment, get_offer, np. atal. Tylko z city. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | |
| items | Yes | |
| total | Yes | Wszystkie pasujące; null, gdy serwis nie podaje (szukanie po nazwie). |
| returned | Yes | |
| truncated | Yes | true: pasujących jest więcej, niż pokazano; co zawęzić, mówi hint. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint and openWorldHint, so the description carries the real behavioral load: it discloses that city mode returns only investments the site shows on the city map (those without active offers may be absent), that averages cover active offers only, that items without an average sort last, and that total/returned/truncated/hint report what was cut. It even flags that links should be surfaced to the user.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the two modes, then grouped into return fields and limits. Dense and mostly waste-free, though the enumerated return-field list partially duplicates what the output schema already provides and could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter search tool with an output schema, annotations, and eleven siblings, nothing an agent needs is missing: mode selection, field availability per mode, sorting behavior, filtering exclusions, and truncation reporting are all covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds cross-parameter semantics the schema does not: which parameters only work together with city (sort, developer_slug), how name alone switches to nationwide site-ordered search, and a practical sizing rule for limit (roughly 550–750 output characters per city item).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Wyszukuje inwestycje – projekty deweloperskie, rynek pierwotny') and immediately distinguishes the two operating modes (city = full data, name-only = whole Poland with a reduced field set). An agent can tell this apart from search_offers and get_investment without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance with concrete examples (cheapest per m² in a city, one developer's projects, slug lookup by name) and names the boundary against siblings: price/area filtering goes to search_offers, offer and project details go to get_investment. It also states the negative case (city=polska does not work).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_locationsSzukaj lokalizacjiARead-only
Znajduje miasta, dzielnice i ulice w Polsce po fragmencie nazwy. Użyj na początku, żeby zamienić nazwę miejsca na city_slug, którego wymaga search_offers. Nie zwraca ofert ani cen.
Zwraca items (kind: city, district albo street; name, city, city_slug, opcjonalnie district, street, lat, lng i offer_count, czyli liczbę ofert wg serwisu) oraz total, returned, truncated i hint. total jest null, gdy wyników jest więcej niż pokazano; truncated=true znaczy, że pasujących może być więcej: doprecyzuj nazwę. Miejscowości z offer_count=0 nie mają ofert: nie przekazuj ich do search_offers. Dzielnica i ulica podają city_slug swojego miasta. Nazwę dzielnicy (kind=district, pole name) przekaż do search_offers jako district razem z tym city_slug; po ulicy search_offers nie filtruje.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Fragment nazwy miasta, dzielnicy lub ulicy, 2–100 znaków, z polskimi znakami, np. Kraków, Mokotów. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | |
| items | Yes | |
| total | Yes | Wszystkie pasujące; null, gdy wyników jest więcej niż pokazano. |
| returned | Yes | |
| truncated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/open-world safety, and the description adds valuable semantics beyond them: total=null meaning, truncated=true handling, offer_count=0 exclusion, and that search_offers does not filter by street. Much of the raw field list is redundant with the existing output schema, so it stops short of a full 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, followed by usage, then output semantics; every sentence is information-dense. It is somewhat long and the itemized field list borders on redundancy given the output schema, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a single-param tool with an output schema and read-only annotations, the description covers purpose, the sibling dependency, edge-case semantics (truncation, zero-offer filtering), and downstream usage. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single query param is fully documented in the schema (length, Polish characters, examples). The description restates it as a name fragment without adding syntax or format beyond what the schema already provides, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: finds cities, districts and streets in Poland by name fragment. It explicitly distinguishes itself from siblings by noting it returns neither offers nor prices, which sets it apart from search_offers. An agent can identify its role immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to use it at the beginning to convert a place name into the city_slug required by search_offers, giving the exact ordering and dependency. It also states when NOT to forward results (offer_count=0) and how district/street map to search_offers parameters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_offersSzukaj ofert mieszkańARead-only
Wyszukuje oferty mieszkań od deweloperów (tylko rynek pierwotny, ceny ofertowe, nie transakcyjne) w jednym mieście albo w jego dzielnicy; city=polska nie działa. city_slug i nazwę dzielnicy daje search_locations. Filtry: cena, metraż, cena za m², dzielnica, status (aktywne, archiwalne) i obniżka od pierwszej ceny; sortowanie po cenie, cenie za m², metrażu albo największej obniżce; lista ofert nie filtruje po pokojach ani piętrze, ani po deweloperze (jego inwestycje daje get_developer).
Zwraca jedną stronę: total (wszystkie pasujące), returned, page, per_page, pages_available, truncated, hint, list_url i items (offer_id, investment_slug, investment_url, name, cena w PLN, metraż w m², cena za m², status, inwestycja z dzielnicą, deweloper z developer_slug, zmiany ceny w procentach). Pozycje są skrócone; szczegóły oferty i historię ceny daje get_offer. Linki podawaj użytkownikowi.
Ograniczenia: można przejrzeć najwyżej 20 stron po per_page ofert. Gdy truncated=true, zawęź filtry (np. dzielnica, cena) zamiast przeglądać kolejne strony. Wszystkie oferty jednej inwestycji daje get_investment, ceny całego miasta get_market_statistics.
| Name | Required | Description | Default |
|---|---|---|---|
| city | Yes | city_slug jednego miasta z search_locations, np. warszawa, krakow (nie polska: serwis nie ma listy ofert całego kraju). | |
| page | No | Numer strony wyników, 1–20 (dalej serwis nie udostępnia: zawęź filtry). | |
| sort | No | price_asc: od najtańszych, price_desc: od najdroższych, price_per_m2_asc i price_per_m2_desc: po cenie za m², area_asc i area_desc: po metrażu, biggest_drop: najpierw największa obniżka od pierwszej ceny (w %); brak: domyślna kolejność serwisu (nie jest gwarantowana; zwykle najstarsze oferty, grupami po inwestycji; to nie ranking), więc do przeglądu miasta podaj sort. | |
| status | No | active (domyślnie): oferty obecnie w cennikach; archived: tylko wycofane; all: aktywne i wycofane (total przy all może być większy niż suma active i archived: serwis liczy je niejasno). | active |
| area_max | No | Największy metraż w m². | |
| area_min | No | Najmniejszy metraż w m². | |
| district | No | Nazwa dzielnicy, np. Mokotów albo Praga-Południe (wielkość liter, polskie znaki, spacje i myślniki nie mają znaczenia); razem z city_slug jej miasta. Lista dzielnic: search_locations (kind=district). | |
| per_page | No | 10 albo 50. Pozycja to ok. 500 znaków wyniku (z linkiem), więc 50 daje ok. 25 tys.; zwykle wystarcza 10. | |
| price_max | No | Najwyższa cena oferty w PLN. | |
| price_min | No | Najniższa cena oferty w PLN. | |
| price_dropped | No | true: tylko oferty, których obecna cena jest niższa od pierwszej ceny (liczy się zmiana od pierwszej ceny, nie ostatnia zmiana). | |
| price_per_m2_max | No | Najwyższa cena za m² w PLN. | |
| price_per_m2_min | No | Najniższa cena za m² w PLN. |
Output Schema
| Name | Required | Description |
|---|---|---|
| hint | No | |
| page | Yes | |
| items | Yes | |
| total | Yes | |
| list_url | No | Ta lista ofert na deweloperuch.pl (te same filtry, sortowanie i strona): podaj ją użytkownikowi jako link. |
| per_page | Yes | |
| returned | Yes | |
| truncated | Yes | true: pasujących ofert jest więcej, niż można przejrzeć (najwyżej 20 stron); zawęź filtry. |
| pages_available | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is known. Beyond that the description discloses genuinely useful behaviour: a hard 20-page ceiling, what truncated=true means and the instruction to narrow filters rather than page further, and the caveat that status=all totals are computed inconsistently upstream. These are substantive additions, but return-format detail overlaps with the output schema, so it sits comfortably above a bare baseline rather than at the top.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded and organised into purpose, return shape and limits, and each block carries real information. However the semicolon-chained sentences are dense, and the item-field enumeration duplicates the existing output schema, which is exactly the kind of repetition that dilutes a definition without adding value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter, paginated, cross-referenced search tool this covers what an agent needs: entry prerequisites, filter capabilities, pagination limits and truncation handling, plus routing to get_offer and get_investment for depth. Given an output schema already exists, the field-by-field return listing is redundant rather than filling a gap, which is the only shortfall.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, yet the description still adds meaning the schema lacks: it enumerates the supported filter set, explains that an omitted sort yields an unguaranteed, non-ranking default order (so an agent should always pass sort), and warns that price_dropped keys off the change from the first price. It also documents the negative space — no room, floor or developer filters — which is parameter semantics no schema can express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and resource ('Wyszukuje oferty mieszkań od deweloperów') plus hard scope boundaries: primary market only, asking prices rather than transaction prices, one city or one district, and the explicit caveat that city=polska does not work. It also names the siblings that serve different purposes (get_offer, get_investment, get_developer, search_locations), so an agent can separate this tool from its neighbours without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to call it (city or district level search) and when not to (no room/floor/developer filtering; use get_developer for a developer's projects, get_investment for all offers in one investment, get_market_statistics for city-wide price levels). It also gives the exact preconditions: obtain city_slug and district names from search_locations, because the city value must be a single-city slug.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.2.0- Changed
estimate_property_value1 field changed- added
Output schema / properties / low_confidenceAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "description": "true: wycena o niskiej wiarygodności (mniej niż 5 transakcji porównawczych); hint mówi, na czym się opiera. Podaj ją tylko jako orientacyjną, z zastrzeżeniem z hint. Jest przy każdej wycenie, brak przy estimated_value=null.", + "title": "Low Confidence" +}
- Changed
get_building8 fields changed- changed
Output schema / $defs / NeighbourhoodTrendResult / properties / total / descriptionPrevious value: -"Wszystkie kwartały, które ma serwis."New value: +"Wszystkie kwartały, które ma serwis (0: brak trendu)." - added
Output schema / properties / hintAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Co zrobić dalej albo czego brakuje w wyniku, np. brak trendu w okolicy budynku.", + "title": "Hint" +} - added
Output schema / properties / name / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - added
Output schema / properties / name / defaultAdded value: +null - changed
Output schema / properties / name / descriptionPrevious value: -"Adres budynku wg rejestru cen."New value: +"Adres budynku wg rejestru cen; brak pola: rejestr nie podaje adresu (miejscowość w city)." - removed
Output schema / properties / name / typeRemoved value: -"string" - added
Output schema / properties / non_regular_transactionsAdded value: +{ + "anyOf": [ + { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Transakcje z classification innym niż regular w całym budynku: liczba wg rodzaju (słowa jak w classification), np. {\"share\": 1}; brak pola: brak takich transakcji. To nie zwykła sprzedaż całego lokalu po cenie rynkowej: nie uśredniaj ich ze zwykłymi. Średnie avg_* serwisu prawdopodobnie ich nie obejmują (sprawdzone w jednym budynku).", + "title": "Non Regular Transactions" +} - changed
Output schema / requiredPrevious value: -[ - "building_slug", - "name", - "city", - "city_slug", - "units_total", - "transactions_total", - "units", - "units_returned", - "units_omitted", - "truncated" -]New value: +[ + "building_slug", + "city", + "city_slug", + "units_total", + "transactions_total", + "units", + "units_returned", + "units_omitted", + "truncated" +]
- Changed
get_developer12 fields changed- changed
Input schema / properties / city / descriptionPrevious value: -"city_slug miasta z search_locations (np. krakow) albo polska (domyślnie: cała Polska)."New value: +"city_slug miasta z search_locations albo z cities wyniku get_developer (np. krakow), albo polska (domyślnie: cała Polska)." - changed
Input schema / properties / developer_slug / descriptionPrevious value: -"developer_slug z search_developers (po nazwie) albo z pól developer_slug w search_offers, get_investment, get_offer, np. atal."New value: +"developer_slug z search_developers (po nazwie) albo z pól developer_slug w search_offers, get_investment, get_offer, get_market_statistics (top_developers), np. atal." - changed
Input schema / properties / limit / descriptionPrevious value: -"Najwięcej inwestycji w wyniku (najpierw te z największą liczbą aktywnych ofert), 1–100, domyślnie 20. Inwestycja to ok. 350 znaków wyniku; zwykle wystarcza domyślne 20."New value: +"Najwięcej inwestycji w wyniku (najpierw te z największą liczbą aktywnych ofert), 1–100, domyślnie 20. Inwestycja to 350–400 znaków wyniku; zwykle wystarcza domyślne 20." - removed
Output schema / $defs / DeveloperBrief / properties / websiteRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Website" -} - added
Output schema / $defs / DeveloperCityItem / properties / active_offers / descriptionAdded value: +"Aktywne oferty dewelopera w mieście." - removed
Output schema / $defs / DeveloperCityItem / properties / avg_priceRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Średnia cena aktywnych ofert w PLN.", - "title": "Avg Price" -} - added
Output schema / $defs / DeveloperCityItem / properties / avg_price_per_m2 / descriptionAdded value: +"Średnia cena za m² aktywnych ofert wg serwisu albo liczona z inwestycji." - added
Output schema / $defs / DeveloperInvestmentItem / properties / active_offers / descriptionAdded value: +"Aktywne oferty inwestycji." - added
Output schema / $defs / DeveloperInvestmentItem / properties / avg_area_m2 / descriptionAdded value: +"Średni metraż aktywnych ofert." - added
Output schema / $defs / DeveloperInvestmentItem / properties / avg_price_per_m2 / descriptionAdded value: +"Cena za m² aktywnych ofert: ich łączna cena przez łączny metraż." - changed
Output schema / $defs / DeveloperSummaryItem / properties / avg_price_per_m2 / descriptionPrevious value: -"Średnia cena za m² aktywnych ofert wg serwisu."New value: +"Średnia cena za m² aktywnych ofert: ceny za m² inwestycji ważone liczbą ich ofert (jak w serwisie), liczona z inwestycji; dla jednego miasta może różnić się o 1 zł od wiersza w cities i nie jest ilorazem avg_price / avg_area_m2." - changed
Output schema / properties / cities / descriptionPrevious value: -"Wszystkie miasta dewelopera w Polsce, niezależnie od argumentu city (także przy city=warszawa)."New value: +"Wszystkie miasta dewelopera w Polsce, niezależnie od argumentu city (także przy city=warszawa), od miasta z największą liczbą aktywnych ofert."
- Changed
get_government_statistics2 fields changed- changed
Input schema / properties / dataset / descriptionPrevious value: -"dwellings_quarterly: mieszkania oddane do użytkowania i rozpoczęte (razem, wg form budownictwa, na wynajem), kwartalnie; dwellings_monthly: to samo miesięcznie; average_area: średnia powierzchnia mieszkania oddanego przez deweloperów (m², rocznie); demography: urodzenia żywe, zgony, przyrost naturalny (dla Polski miesięcznie, dla miast rocznie); population: ludność, kobiety i mężczyźni (rocznie); unemployment: stopa bezrobocia rejestrowanego (%, miesięcznie); wages: przeciętne miesięczne wynagrodzenie brutto w PLN (dla Polski miesięcznie, dla miast rocznie, czasem z relacją do średniej krajowej); nbp_prices: średnie ceny m² wg NBP, rynek pierwotny i wtórny, ofertowe i transakcyjne (PLN/m², kwartalnie). Częstotliwość zwraca pole frequency."New value: +"dwellings_quarterly: mieszkania oddane do użytkowania i rozpoczęte (razem, wg form budownictwa, na wynajem), kwartalnie; dwellings_monthly: to samo miesięcznie; average_area: średnia powierzchnia mieszkania oddanego przez deweloperów (m², rocznie); demography: urodzenia żywe, zgony, przyrost naturalny (dla Polski miesięcznie wg Eurostatu, dla miast rocznie wg GUS); population: ludność, kobiety i mężczyźni (rocznie); unemployment: stopa bezrobocia rejestrowanego (%, miesięcznie); wages: przeciętne miesięczne wynagrodzenie brutto w PLN (dla Polski miesięcznie, dla miast rocznie, czasem z relacją do średniej krajowej); nbp_prices: średnie ceny m² wg NBP, rynek pierwotny i wtórny, ofertowe i transakcyjne (PLN/m², kwartalnie). Częstotliwość zwraca pole frequency. Agregat 7-miast nie ma wages ani unemployment (są dla miast i polska)." - changed
Input schema / properties / location / descriptionPrevious value: -"polska (cała Polska), agregat 7-miast, 10-miast albo 6-miast-bez-warszawy, albo jedno z 66 miast na prawach powiatu: nazwa małymi literami bez polskich znaków, z myślnikami zamiast spacji, np. warszawa, krakow, lodz, bielsko-biala, zielona-gora; Jastrzębie-Zdrój to jastrzebie. Dane są tylko dla 66 miast na prawach powiatu, a nie dla dzielnic i mniejszych miejscowości."New value: +"polska (cała Polska), agregat 7-miast, 10-miast albo 6-miast-bez-warszawy, albo jedno z 66 miast na prawach powiatu: nazwa małymi literami bez polskich znaków, z myślnikami zamiast spacji, np. warszawa, krakow, lodz, bielsko-biala, zielona-gora, jastrzebie-zdroj. Dane są tylko dla 66 miast na prawach powiatu, a nie dla dzielnic i mniejszych miejscowości."
- Changed
get_investment3 fields changed- changed
Input schema / properties / include_history / descriptionPrevious value: -"true: dołącz historię ceny każdej zwróconej oferty (dłuższy wynik)."New value: +"true: dołącz price_history każdej zwróconej oferty (ok. 150 znaków więcej na ofertę)." - changed
Input schema / properties / limit / descriptionPrevious value: -"Najwięcej ofert w wyniku (najpierw aktywne), domyślnie 20, 0 = tylko podsumowanie inwestycji. Ile pominięto, mówi offers_omitted. Każda oferta to ok. 300 znaków wyniku, z historią ceny kilkaset więcej. Maksimum 200 daje ok. 60 tys. znaków; zwykle wystarcza domyślne 20."New value: +"Najwięcej ofert w wyniku (najpierw aktywne), domyślnie 20, 0 = tylko podsumowanie inwestycji. Ile pominięto, mówi offers_omitted. Każda oferta to ok. 300 znaków wyniku, z historią ceny ok. 450 (zdarzenie to ok. 55 znaków). Maksimum 200 daje ok. 60 tys. znaków; zwykle wystarcza domyślne 20." - added
Output schema / $defs / InvestmentOfferItem / properties / price_history / descriptionAdded value: +"Zdarzenia ceny oferty od najstarszego; tylko z include_history=true."
- Changed
get_market_statistics4 fields changed- added
Output schema / $defs / DeveloperShareItem / properties / developer_nameAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Nazwa dewelopera.", + "title": "Developer Name" +} - changed
Output schema / $defs / DeveloperShareItem / properties / developer_slug / descriptionPrevious value: -"Identyfikator dewelopera (bez nazwy); nazwę i inwestycje daje get_developer."New value: +"Identyfikator dewelopera: inwestycje i ceny daje get_developer (city = city_slug wyniku)." - added
Output schema / properties / as_ofAdded value: +{ + "anyOf": [ + { + "format": "date", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Dzień, na który serwis podał oferty (może być wczorajszy): podawaj go przy liczbach.", + "title": "As Of" +} - added
Output schema / properties / investments / descriptionAdded value: +"Inwestycje z pasującymi ofertami."
- Changed
get_transaction_statistics9 fields changed- changed
Input schema / properties / city / descriptionPrevious value: -"city_slug miasta z search_locations, np. warszawa, krakow, gdansk (małe litery bez polskich znaków). Statystyki są dla całych miast; dzielnice, ulice i cała Polska (polska) nie są obsługiwane."New value: +"city_slug miasta z search_locations, np. warszawa, krakow, gdansk (małe litery bez polskich znaków). Statystyki są dla całych miast; dzielnice, ulice, agregaty miast (np. 7-miast) i cała Polska (polska) nie są obsługiwane." - changed
Input schema / properties / granularity / descriptionPrevious value: -"month (domyślnie): miesiące, z medianą i średnią ceny za m², medianą metrażu i medianą ceny mieszkania; quarter: kwartały, tylko średnia cena za m² i liczba transakcji, ale dłuższa historia."New value: +"month (domyślnie): miesiące, tylko rynek wtórny, z medianą i średnią ceny za m², medianą metrażu i medianą ceny mieszkania; quarter: kwartały, tylko mediana ceny za m² i liczba transakcji (rynek nieokreślony), za to cała historia od 2017 r. w jednym wywołaniu (periods=60)." - changed
Output schema / $defs / TransactionPeriodItem / properties / average_price_per_m2 / descriptionPrevious value: -"Średnia cena transakcyjna 1 m² w PLN."New value: +"Średnia cena transakcyjna 1 m² w PLN (tylko granularity=month)." - added
Output schema / $defs / TransactionPeriodItem / properties / incompleteAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "description": "true: okres ma mniej niż połowę zwykłej liczby transakcji, bo dane RCN są jeszcze niepełne; nie wyciągaj wniosków z jego cen ani liczby transakcji. Pole jest tylko przy takich okresach.", + "title": "Incomplete" +} - changed
Output schema / $defs / TransactionPeriodItem / properties / median_area_m2 / descriptionPrevious value: -"Mediana metrażu w m² (tylko month)."New value: +"Mediana metrażu w m² (tylko granularity=month)." - changed
Output schema / $defs / TransactionPeriodItem / properties / median_price / descriptionPrevious value: -"Mediana ceny transakcyjnej mieszkania w PLN (tylko month)."New value: +"Mediana ceny transakcyjnej mieszkania w PLN (tylko granularity=month)." - changed
Output schema / $defs / TransactionPeriodItem / properties / median_price_per_m2 / descriptionPrevious value: -"Mediana ceny transakcyjnej 1 m² w PLN (tylko month)."New value: +"Mediana ceny transakcyjnej 1 m² w PLN." - changed
Output schema / properties / hint / descriptionPrevious value: -"Co zrobić dalej, gdy wynik jest obcięty."New value: +"Co zrobić dalej: gdy wynik jest obcięty, ma okresy incomplete albo za mało transakcji, by je ocenić." - added
Output schema / properties / last_complete_periodAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Najnowszy okres ze zwykłą liczbą transakcji (nie incomplete), pokazany lub nie; na nim kończ trend, choć jego dane mogą się jeszcze zmienić. Brak pola: za krótka historia albo za mało transakcji, by to ocenić.", + "title": "Last Complete Period" +}
- Changed
rank_locations35 fields changed- added
Input schema / properties / indicatorAdded value: +{ + "anyOf": [ + { + "enum": [ + "unemployment_rate", + "average_wage", + "dwellings_completed", + "dwellings_started", + "average_dwelling_area", + "natural_increase", + "nbp_price_per_m2" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Ranking 66 miast na prawach powiatu według wskaźnika zamiast transakcji (bez level=powiat, min_transactions i market): unemployment_rate: stopa bezrobocia rejestrowanego (%) w miesiącu; average_wage: przeciętne miesięczne wynagrodzenie brutto (PLN), średnia za rok period (jak dataset=wages w get_government_statistics); dwellings_completed, dwellings_started: mieszkania oddane, rozpoczęte w 12 miesiącach do miesiąca period; average_dwelling_area: powierzchnia mieszkania (m²) podana przez serwis za okres period; nie porównuj jej z average_area z get_government_statistics (inna definicja); natural_increase: przyrost naturalny (osoby) w roku; nbp_price_per_m2: cena transakcyjna rynku wtórnego wg NBP (PLN/m²) w kwartale, tylko 17 miast. Miasta bez wartości są pominięte (hint).", + "title": "Wskaźnik" +} - changed
Input schema / properties / level / descriptionPrevious value: -"city: miejscowości (miasta, także małe miasteczka i wsie), domyślnie; powiat: powiaty (bez ranking_url i bez odpowiednika w search_locations)."New value: +"city: miejscowości (miasta, także małe miasteczka i wsie), domyślnie; powiat: powiaty, tylko transakcje (market); powiaty nie mają city_slug ani ranking_url i nie ma ich w search_locations. Z indicator tylko city." - added
Input schema / properties / marketAdded value: +{ + "anyOf": [ + { + "enum": [ + "secondary", + "primary", + "all" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Tylko level=powiat. secondary: rynek wtórny (domyślnie); primary: pierwotny; all: oba rynki w zestawieniu serwisu (jego liczba transakcji nie zawsze równa się secondary + primary). Powiaty bez danych dla rynku są pominięte (hint).", + "title": "Rynek" +} - added
Input schema / properties / min_transactions / anyOfAdded value: +[ + { + "maximum": 10000000, + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / min_transactions / defaultPrevious value: -0New value: +null - changed
Input schema / properties / min_transactions / descriptionPrevious value: -"Pomiń miejsca z mniejszą liczbą transakcji; domyślnie 0 (wszystkie). Przy sortowaniu miejscowości (level=city) po cenie podaj np. 50."New value: +"Brak = próg domyślny: 20 przy sortowaniu po cenie, 0 przy transactions_desc. 0 = wszystkie miejsca. Pomija miejsca z mniejszą liczbą transakcji; np. 50 daje stabilniejsze ceny. Nie działa z indicator." - removed
Input schema / properties / min_transactions / maximumRemoved value: -10000000 - removed
Input schema / properties / min_transactions / minimumRemoved value: -0 - removed
Input schema / properties / min_transactions / typeRemoved value: -"integer" - added
Input schema / properties / sort / anyOfAdded value: +[ + { + "enum": [ + "transactions_desc", + "price_per_m2_desc", + "price_per_m2_asc", + "value_desc", + "value_asc" + ], + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / sort / defaultPrevious value: -"transactions_desc"New value: +null - changed
Input schema / properties / sort / descriptionPrevious value: -"transactions_desc: najwięcej transakcji (domyślnie); price_per_m2_desc: najwyższa cena za m²; price_per_m2_asc: najniższa cena za m². Miejsca bez ceny są na końcu."New value: +"transactions_desc: najwięcej transakcji (domyślnie bez indicator); price_per_m2_desc, price_per_m2_asc: najwyższa, najniższa cena za m² (miejsca bez ceny na końcu); value_desc (domyślnie z indicator), value_asc: najwyższa, najniższa wartość wskaźnika, tylko z indicator." - removed
Input schema / properties / sort / enumRemoved value: -[ - "transactions_desc", - "price_per_m2_desc", - "price_per_m2_asc" -] - removed
Input schema / properties / sort / typeRemoved value: -"string" - added
Output schema / $defs / RankedLocationItem / properties / stats_urlAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Link do strony wskaźnika miasta na deweloperuch.pl (tylko z indicator): podaj go użytkownikowi.", + "title": "Stats Url" +} - added
Output schema / $defs / RankedLocationItem / properties / transaction_count / anyOfAdded value: +[ + { + "type": "integer" + }, + { + "type": "null" + } +] - added
Output schema / $defs / RankedLocationItem / properties / transaction_count / defaultAdded value: +null - changed
Output schema / $defs / RankedLocationItem / properties / transaction_count / descriptionPrevious value: -"Liczba transakcji wg serwisu; okresu serwis nie podaje (dla powiatów wiele lat: tylko do uporządkowania)."New value: +"Liczba transakcji wg serwisu: dla powiatu w okresie period_start–period_end, dla miejscowości w okresie, którego serwis nie podaje." - removed
Output schema / $defs / RankedLocationItem / properties / transaction_count / typeRemoved value: -"integer" - added
Output schema / $defs / RankedLocationItem / properties / valueAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Wartość wskaźnika (indicator) w jednostce unit za okres period.", + "title": "Value" +} - changed
Output schema / $defs / RankedLocationItem / requiredPrevious value: -[ - "name", - "transaction_count" -]New value: +[ + "name" +] - changed
Output schema / properties / hint / descriptionPrevious value: -"Co zrobić, gdy wynik jest obcięty albo pusty."New value: +"Co zrobić, gdy wynik jest obcięty albo pusty, oraz co pominięto: małe miejsca przy sortowaniu po cenie (domyślny próg), powiaty bez danych dla market, miasta bez wskaźnika." - added
Output schema / properties / indicatorAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Wskaźnik rankingu, jak w argumencie.", + "title": "Indicator" +} - added
Output schema / properties / marketAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Rynek rankingu powiatów: secondary, primary albo all.", + "title": "Market" +} - added
Output schema / properties / min_transactions / anyOfAdded value: +[ + { + "type": "integer" + }, + { + "type": "null" + } +] - added
Output schema / properties / min_transactions / defaultAdded value: +null - changed
Output schema / properties / min_transactions / descriptionPrevious value: -"Próg z argumentu min_transactions (0 = wszystkie miejsca)."New value: +"Zastosowany próg: min_transactions z argumentu, a bez niego domyślny: 20 przy sortowaniu po cenie, 0 przy transactions_desc (0 = wszystkie miejsca). Brak przy indicator." - removed
Output schema / properties / min_transactions / typeRemoved value: -"integer" - added
Output schema / properties / periodAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Okres wartości wskaźnika: miesiąc (RRRR-MM), kwartał (RRRR-Qn) albo rok (RRRR); dla dwellings_completed i dwellings_started ostatni miesiąc okna 12 miesięcy.", + "title": "Period" +} - added
Output schema / properties / period_endAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Ostatni miesiąc okresu transakcji powiatów (RRRR-MM), wliczony w okres.", + "title": "Period End" +} - added
Output schema / properties / period_startAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Pierwszy dzień okresu transakcji powiatów (RRRR-MM-01).", + "title": "Period Start" +} - changed
Output schema / properties / ranking_url / descriptionPrevious value: -"Strona rankingu miast na deweloperuch.pl (tylko level=city): podaj ją użytkownikowi jako link."New value: +"Strona rankingu miast na deweloperuch.pl (tylko level=city bez indicator): podaj ją użytkownikowi jako link." - changed
Output schema / properties / total / descriptionPrevious value: -"Wszystkie miejsca tego poziomu z co najmniej min_transactions transakcji."New value: +"Wszystkie miejsca spełniające kryteria: z co najmniej min_transactions transakcji, z danymi dla market albo z wartością wskaźnika." - added
Output schema / properties / unitAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Jednostka value: %, PLN/mies., mieszkania (suma 12 miesięcy), m², osoby albo PLN/m².", + "title": "Unit" +} - changed
Output schema / requiredPrevious value: -[ - "level", - "sort", - "min_transactions", - "total", - "returned", - "truncated", - "items" -]New value: +[ + "level", + "sort", + "total", + "returned", + "truncated", + "items" +]
- Changed
search_offers10 fields changed- changed
Input schema / properties / city / descriptionPrevious value: -"city_slug miasta z search_locations (np. warszawa, krakow) albo polska dla całego kraju."New value: +"city_slug jednego miasta z search_locations, np. warszawa, krakow (nie polska: serwis nie ma listy ofert całego kraju)." - changed
Input schema / properties / district / descriptionPrevious value: -"Nazwa dzielnicy dokładnie tak, jak podaje ją search_locations (kind=district, pole name), np. Mokotów; tylko z miastem tej dzielnicy, nie z polska."New value: +"Nazwa dzielnicy, np. Mokotów albo Praga-Południe (wielkość liter, polskie znaki, spacje i myślniki nie mają znaczenia); razem z city_slug jej miasta. Lista dzielnic: search_locations (kind=district)." - changed
Input schema / properties / page / descriptionPrevious value: -"Numer strony wyników, 1–20."New value: +"Numer strony wyników, 1–20 (dalej serwis nie udostępnia: zawęź filtry)." - changed
Input schema / properties / sort / descriptionPrevious value: -"price_asc: od najtańszych, price_desc: od najdroższych, price_per_m2_asc i price_per_m2_desc: po cenie za m², area_asc i area_desc: po metrażu, biggest_drop: najpierw największa obniżka od pierwszej ceny (w %); brak: domyślna kolejność serwisu (nie jest gwarantowana)."New value: +"price_asc: od najtańszych, price_desc: od najdroższych, price_per_m2_asc i price_per_m2_desc: po cenie za m², area_asc i area_desc: po metrażu, biggest_drop: najpierw największa obniżka od pierwszej ceny (w %); brak: domyślna kolejność serwisu (nie jest gwarantowana; zwykle najstarsze oferty, grupami po inwestycji; to nie ranking), więc do przeglądu miasta podaj sort." - changed
Input schema / properties / status / descriptionPrevious value: -"active (domyślnie): oferty obecnie w cennikach; archived: tylko wycofane; all: aktywne i wycofane."New value: +"active (domyślnie): oferty obecnie w cennikach; archived: tylko wycofane; all: aktywne i wycofane (total przy all może być większy niż suma active i archived: serwis liczy je niejasno)." - removed
Output schema / $defs / OfferItem / properties / cityRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Tylko przy city=polska.", - "title": "City" -} - removed
Output schema / $defs / OfferItem / properties / city_slugRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Tylko przy city=polska.", - "title": "City Slug" -} - added
Output schema / $defs / OfferItem / properties / districtAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Dzielnica inwestycji, nazwa jak w search_locations (kind=district): można ją podać w district. Brak, gdy serwis jej nie podaje (np. Sopot).", + "title": "District" +} - changed
Output schema / $defs / OfferItem / properties / last_price_change_kind / descriptionPrevious value: -"increase, decrease albo no_change."New value: +"increase, decrease, no_change albo new_offer (oferta bez zmiany ceny od dodania)." - added
Output schema / $defs / OfferItem / properties / name / descriptionAdded value: +"Oznaczenie mieszkania u dewelopera (np. A2, D1.1.1.4); nazwa inwestycji jest w investment_name."
13 tool updates
v0.1.3- First observed
estimate_property_value - First observed
get_building - First observed
get_developer - First observed
get_government_statistics - First observed
get_investment - First observed
get_market_statistics - First observed
get_offer - First observed
get_transaction_statistics - First observed
rank_locations - First observed
search_developers - First observed
search_investments - First observed
search_locations - First observed
search_offers
TDQS
Scored across 13 tools
Most tools target clearly distinct resources or actions (offers, investments, developers, buildings, locations), and descriptions explicitly cross-reference alternatives. The main potential confusion is among the three statistics tools (market, transaction, government) and rank_locations, but their scopes are spelled out well enough to prevent most misselection.
All tool names use snake_case and a predictable verb_noun pattern: search_locations, search_offers, get_investment, get_developer, get_market_statistics, estimate_property_value. Related tools share suffixes such as *_statistics and search_* consistently.
The 13 tools are well-scoped for a real-estate data server, with each tool covering a distinct entity or analysis type. There are no obvious filler or redundant tools, and the count sits comfortably in the appropriate range.
The surface covers location lookup, offer search, offer/investment/developer detail, building transactions, market/transaction/government statistics, ranking, and valuation. A minor gap is building discovery: get_building requires a user-supplied slug, and there is no search_buildings by address or name, though workarounds via search_locations and user links exist.
Maintenance
Related MCP Connectors
An open MCP server for the Portuguese housing market, run by flatin.pt. No API key, no registration, no rate-limit negotiation. Twelve tools: • imt_calculate — IMT and Imposto do Selo on a purchase, 2026 tables, including the reduced table, the relief for buyers aged 35 or under and the flat rate for non-residents • imi_rate / imi_annual_cost — the IMI rate of any of the 308 municipalities for 2023–2025, and the annual bill for a given VPT • construction_barometer — how many building-permit cases enter a town hall each month (our own indicator: monthly for three municipalities, annual for eight, method and revision policy published) • search_newbuilds / get_newbuild — 250 new developments, 53 municipalities, 71 developers, with stage and, where published, price • where_to_live / municipality_stats / compare_municipalities — municipal comparisons • glossary_lookup — Portuguese property and tax terms • request_consultation / subscribe_digest — reaching a human The data behind the tax tools is published as open data under CC BY 4.0 on the Portuguese national portal (dados.gov.pt) and archived on Zenodo with a permanent DOI. Anyone may reuse it. Humans, not bots, answer the people who get in touch: a home purchase involves personal data under the GDPR and decisions that cannot be refunded.
Pay-per-use tool marketplace for AI agents. Search, price-check, and call APIs via MCP.
Public Data Ukraine Mcp connects AI agents to real public APIs via MCP. Tools include
Housing Intel MCP — Meta-pack that chains FRED, BLS, ATTOM, and HUD APIs into higher-level housing…
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceExposes ATTOM's real estate API as MCP tools, enabling property details, valuations, assessments, sales, and area data via natural language.2-
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to query and analyze Korean property data—court auctions, actual transactions, subscription announcements, price trends, and loan/tax calculations—through MCP tools.MIT
- AlicenseAqualityBmaintenanceGives AI agents read-only access to Bulgarian real-estate data from imotai.bg, letting them list districts, search and fetch active listings, pull district-level market statistics, and estimate values from current asking prices. All results are field-allowlisted and rate limited, with no credentials, broker contact details, or written descriptions exposed.5MIT
- AlicenseAqualityCmaintenanceEnables AI agents to compute Dubai Land Department transaction fees, rental yields, Central Bank mortgage and LTV limits, and Golden Visa eligibility thresholds, while querying curated off-plan developments and district price benchmarks. It exposes these as deterministic MCP tools, resources, and prompt templates over stdio transport.5MIT