flatin.pt — Portuguese homes: taxes, construction, new-builds
Server Details
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.
- Status
- Healthy
- Uptime
- 99.3% over 42 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
- Server Listing
- flatin
TDQS
Scored across 15 tools
Descriptions are unusually explicit about boundaries, with each tool naming the sibling tools it must not be used for (municipality_stats vs compare_municipalities vs where_to_live, imi_rate vs imi_annual_cost, request_consultation vs submit_consultation). There is residual overlap — municipality_stats already returns IMI rates and building cases that imi_rate and construction_barometer/municipality_housing_pipeline also serve — but the guidance reliably resolves it.
Uniform snake_case with no style drift, and most names are verb_noun or clean noun phrases (compare_municipalities, get_newbuild, search_newbuilds, glossary_lookup). A few names are bare noun phrases whose action is implicit (municipality_stats, construction_barometer, required_income, where_to_live), which is a minor deviation rather than an inconsistency.
Fifteen tools map cleanly onto distinct jobs in a rich domain: search/detail for new builds, three tax calculators plus income, four municipality data views, glossary, guide, and a two-step consultation plus digest. Every tool has a stated reason to exist and nothing appears redundant.
The surface covers discovery, detail, taxation, affordability, local data, and consent-gated contact/subscription flows without obvious dead ends. Gaps are minor but real: there is no unsubscribe/manage-digest operation and no way to retrieve or cancel a previously submitted consultation.
Available Tools
15 toolscompare_municipalitiesCompare 2 to 5 Portuguese municipalitiesARead-onlyIdempotentInspect
Use this when the person is choosing between two to five Portuguese municipalities, with the same figures for each as municipality_stats. Do not use it for a single municipality (municipality_stats) or for the areas inside one city (where_to_live). Names that point at the same municipality count once, and fewer than two distinct ones are refused (bad_count). One unknown or ambiguous name refuses the whole comparison.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | Language of the page links and labels; the text summary and field names stay English. uk is accepted as ua. | en |
| municipalities | Yes | Two to five municipality names or codes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description goes further by disclosing failure modes: duplicate names collapse to one, fewer than two distinct names is refused with bad_count, and one unknown/ambiguous name aborts the whole comparison. That is exactly the trap-handling context an agent needs before calling.
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 short sentences, each earning its place: usage trigger first, exclusions second, edge-case resolution third. No filler and the primary condition is front-loaded.
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?
An output schema exists so return values need no explanation, and annotations cover safety. Combined with the stated error behaviors and the reference to municipality_stats' figures, an agent has everything needed to call this correctly on the first attempt.
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 semantics beyond the schema: entries are resolved as names or codes, duplicates count once, and the distinct count is what must be 2-5. It does not touch the language parameter, though the schema documents that fully.
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 ('compare' + 'two to five Portuguese municipalities') and anchors the output to a known sibling's figures ('same figures for each as municipality_stats'). An agent can immediately distinguish it from municipality_stats and where_to_live.
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 ('person is choosing between two to five municipalities') and explicit when-not, naming both alternatives and the condition that selects each. Nothing 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.
construction_barometerConstruction activity by municipality (barometer)ARead-onlyIdempotentInspect
Use this when the question is how much is being built in Portuguese municipalities. It gives our monthly count of building-works cases entering licensing, where we collect them, and INE's yearly licensed buildings and new dwellings for all 308. Do not use it for other figures (municipality_stats). Without municipality it returns every municipality we collect and the panel index. measure and granularity change only our own series. A case is not a granted licence or a building.
| Name | Required | Description | Default |
|---|---|---|---|
| measure | No | Kind of works counted in our own series: all works, new buildings, or alterations and extensions | total_works |
| language | No | Language of the page links and labels; the text summary and field names stay English. uk is accepted as ua. | en |
| granularity | No | Period of our own series; the INE series is yearly either way | month |
| municipality | No | Optional. Municipality name in any case, accents optional (Porto, Lisboa, Vila Nova de Gaia, Matosinhos; Lisbon and Oporto are accepted) or its four-digit code (1312). Close spellings are found; two matches return an `ambiguous` error with candidates. Omit for the summary of every municipality we collect |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower, but the description adds genuine semantic context beyond them: the dual-series nature ('measure and granularity change only our own series'), the fallback to all municipalities plus a panel index, and the caveat that a case is not a granted licence or a building. It does not mention the `ambiguous` error path, though the schema does.
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?
Five tight sentences with the trigger and exclusion front-loaded and no filler. The token-level density (backticked param names, abbreviations) makes it slightly terse to parse but costs nothing semantically.
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 present, the description needn't explain return shapes, and it covers what an agent actually needs: when to call it, what data it returns, what the two series are, and how the counts should be interpreted. The only opaque term, 'panel index', is resolved by 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%, so baseline is 3, but the description supplies a cross-parameter relationship not visible in per-parameter docs: only the in-house series responds to `measure` and `granularity`, while the INE series stays yearly. It otherwise restates schema content (omit `municipality` for the full panel).
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-plus-resource ('monthly count of building-works cases entering licensing' plus INE licensed buildings and new dwellings) scoped to Portuguese municipalities. It also distinguishes itself from the sibling `municipality_stats`, so an agent can route 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?
Opens with an explicit trigger ('Use this when the question is how much is being built...') and an explicit exclusion ('Do not use it for other figures (`municipality_stats`)'), naming the alternative. The omission behavior for `municipality` is also spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_newbuildGet one new-build project: prices, cost, nearbyARead-onlyIdempotentInspect
Use this when one new-build project in Portugal is needed in detail, by slug (from search_newbuilds) or page URL. It gives units and prices per typology, price history, delivery promises and how often they moved, building permits, the developer, the purchase cost and what is nearby. Do not use it to search (search_newbuilds) or for taxes at another price or for a non-resident (imt_calculate). The purchase cost is at the cheapest available unit or the developer's from-price, for a buyer tax resident in Portugal. primary_home and buyer_is_young change only the purchase cost. An unknown slug is refused (not_found). Cite the page URL, given in all seven site languages.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | The project's slug from search_newbuilds (field slug), or its flatin.pt page URL | |
| language | No | Language of the page URLs and of the labels (stage, typology, nearby places); the text summary shows the typology labels in it. Field names stay English. uk is accepted as ua. | en |
| primary_home | No | For the purchase cost only: the buyer's own permanent home (habitação própria e permanente) | |
| buyer_is_young | No | For the purchase cost only: buyer aged 35 or under, first own home (reduced IMT and stamp duty relief); applies only with primary_home |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive, closed-world behavior, so the bar is lower; the description still adds real context: an unknown slug is refused with not_found, URLs are returned in seven site languages, and the purchase cost is scoped to the cheapest available unit or developer from-price for a tax-resident buyer. This discloses error behavior and calculation assumptions that 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?
The description is front-loaded with the primary use case and the slug/URL lookup, then proceeds through payload, exclusions, and assumptions without filler. It is dense but every clause carries signal; only minor tightening is possible around the repeated search_newbuilds reference.
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 four parameters, an output schema, and full schema coverage, the description provides everything an agent needs to select and invoke the tool: lookup key, returned content categories, exclusion routing, error behavior, and calculation assumptions. Nothing essential 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 the baseline is 3; the description goes beyond by explaining that primary_home and buyer_is_young affect only the purchase cost and that the cost baseline assumes Portuguese tax residency. It also clarifies why language matters (page URLs and labels), though much of that is already 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?
The description states a specific verb and resource ('one new-build project in Portugal ... in detail'), names the lookup key (slug from search_newbuilds or page URL), and enumerates the returned payload (units, prices, history, permits, developer, purchase cost, nearby). It is clearly distinguishable from search_newbuilds and imt_calculate by naming both as out-of-scope.
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 explicitly says when to use it (single project needed in detail) and when not to (searching, taxes at another price, non-resident calculation), routing the agent to search_newbuilds and imt_calculate. The assumption that the cost is for a Portuguese tax resident is stated as a usage condition, not left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
glossary_lookupExplain a Portuguese home-buying termARead-onlyIdempotentInspect
Use this when asked what a Portuguese home-buying or tax term means (CPCV, escritura, VPT…), with where it comes up and the article of law with a link. Do not use it to calculate anything: purchase taxes are imt_calculate, the yearly tax imi_annual_cost. Without term it lists all terms. A term without a translation comes in English; an unknown one is refused with close spellings, if any.
| Name | Required | Description | Default |
|---|---|---|---|
| term | No | The term: Portuguese or English name, a name in any site language or an abbreviation (CPCV, IMT, VPT, caderneta predial, escritura). Omit to list all terms | |
| language | No | Language of the answer: the guide or the definition, the text summary and the page links. Field names stay English. uk is accepted as ua. | en |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish a safe read-only, idempotent, non-destructive lookup, but the description adds substantial context beyond them: it returns where terms come up and the relevant article of law with a link, lists all terms when `term` is omitted, falls back to English when no translation exists, and refuses unknown terms with close spellings.
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?
The description is compact and front-loaded: usage comes first, exclusions second, and fallback behavior last. Every sentence adds operational value, including sibling alternatives, omission behavior, translation fallback, and unknown-term handling.
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?
An output schema exists, so the description need not document return shape. Given the simple two-parameter lookup with annotations and full schema coverage, the description is complete enough to call correctly and understand edge-case behavior.
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 behavioral meaning beyond the schema by explaining what happens when `term` is omitted, when a translation is missing, and when a term is unknown. The `language` fallback and refusal behavior are useful additions, though much of the term/listing guidance is already present 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?
The description states a specific verb-resource action: explaining what a Portuguese home-buying or tax term means, with concrete examples like CPCV, escritura, and VPT. It also distinguishes the tool from sibling calculators by naming imt_calculate and imi_annual_cost, so an agent can identify its role without inspecting other tools.
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 explicitly says when to use the tool (asked what a term means) and when not to use it (calculation tasks), naming the alternative tools for purchase taxes and yearly tax. It also clarifies edge cases such as omitting `term` to list all terms and behavior for unknown terms.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imi_annual_costCalculate the yearly IMI from the taxable valueARead-onlyIdempotentInspect
Use this when the yearly IMI amount on an urban property (prédio urbano) is needed, from its taxable value (VPT) and its municipality's urban rate. Do not use it for the rate alone (imi_rate) or for the one-off purchase taxes (imt_calculate). The VPT is the Tax Authority's valuation on the caderneta predial, not the price: ask the user for it. Only the urban rate is applied; rural property, AIMI and surcharges on vacant homes are not calculated. A municipality whose rate is set per parish is refused (rate_by_freguesia).
| Name | Required | Description | Default |
|---|---|---|---|
| vpt | Yes | Valor Patrimonial Tributário — the taxable value of the property in euros, from the caderneta predial. Not the purchase price | |
| municipality | Yes | Municipality name (Porto, Lisboa or Lisbon, Vila Nova de Gaia) or its four-digit code (1312) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description goes well beyond by scoping the calculation model: only the urban rate is applied, and rural property, AIMI and vacant-home surcharges are excluded. It also flags a hard failure mode (rate_by_freguesia) and a data-source precondition (the VPT must come from the caderneta predial), which are exactly the behavioral facts an agent cannot infer.
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?
Four short sentences, front-loaded with the trigger and followed immediately by exclusions, preconditions, and the refusal case. No restatement of the name or title and no filler; every sentence carries a distinct, actionable constraint.
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 two-parameter read-only calculator with an output schema, everything needed to call it correctly is present: trigger, excluded alternatives, input provenance, calculation scope, and the per-parish refusal condition. Return-value shape is handled by the output schema, so omitting it is correct.
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 both parameters are already documented, and the description deliberately does not restate them. It does add one operational instruction beyond the schema — 'ask the user for it' — telling the agent not to guess or derive the VPT from a price, which slightly exceeds baseline.
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 output ('yearly IMI amount') plus the exact inputs ('taxable value (VPT) and its municipality's urban rate') and the property class it covers ('prédio urbano'). It explicitly names the two siblings it is not (imi_rate, imt_calculate), so an agent can discriminate 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?
Gives an explicit trigger ('Use this when the yearly IMI amount ... is needed') and explicit exclusions with the alternative to pick instead ('Do not use it for the rate alone (imi_rate) or for the one-off purchase taxes (imt_calculate)'). It also defines a refusal case ('A municipality whose rate is set per parish is refused'), which is routing guidance most tools lack.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
imi_rateLook up the IMI rate of a municipalityARead-onlyIdempotentInspect
Use this when only the yearly IMI (municipal property tax) rate of one Portuguese municipality is needed, by name or code, with its history by year. Do not use it for the yearly amount on a VPT (imi_annual_cost) or for several municipalities side by side (compare_municipalities). Rates: Autoridade Tributária portal, all 308 municipalities. Where the rate is set per parish, the answer says so instead of giving a number.
| Name | Required | Description | Default |
|---|---|---|---|
| municipality | Yes | Municipality name (Porto, Lisboa or Lisbon, Vila Nova de Gaia) or its four-digit code (1312) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, it discloses the data source (Autoridade Tributária), full coverage (all 308 municipalities), and an important edge case: per-parish rates return an explanation rather than a number. The output schema already covers return shape, so this is exactly the extra behavioral context that earns credit.
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 sentences, each with a distinct job: when to use, when not to use with named alternatives, then source/coverage/caveat. Front-loaded with the usage decision and zero 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 single-parameter read tool with full annotations and an output schema, everything an agent needs is present: trigger condition, alternatives, data provenance, coverage, and the per-parish fallback behavior.
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 parameter already documents name-or-code with examples, so the schema does the heavy lifting. The description only restates 'by name or code' without adding matching tolerance, casing, or ambiguity handling beyond what the schema shows. 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?
Specific verb and resource ('look up the IMI rate of one Portuguese municipality'), plus explicit scope (single municipality, history by year). It names the two sibling tools it is not, so an agent can distinguish it from imi_annual_cost and compare_municipalities 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?
States the triggering condition ('when only the yearly IMI rate ... of one municipality is needed') and two explicit exclusions mapped to the correct alternatives: imi_annual_cost for VPT amounts, compare_municipalities for side-by-side. Nothing 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.
imt_calculateCalculate IMT and stamp duty on a home purchaseARead-onlyIdempotentInspect
Use this when asked what a home purchase in Portugal costs on top of the price: IMT, stamp duty and Casa Pronta registration, by the 2026 tables. Do not use it for the yearly property tax (imi_annual_cost) or to define a term such as VPT (glossary_lookup). Both taxes are charged on the higher of value and vpt: pass the VPT when known. tax_haven_company takes precedence over non_resident. buyer_is_young applies only when primary_home is true. For a non-resident buyer the answer says what the Tax Authority annuls later on request.
| Name | Required | Description | Default |
|---|---|---|---|
| vpt | No | Optional. The VPT (valor patrimonial tributário) from the caderneta predial, in euros. IMT and stamp duty are charged on the higher of the price and the VPT (CIMT art. 12.º n.º 1), so pass it when it is known | |
| value | Yes | Purchase price as written in the contract, in euros; a dot or a space may group thousands (250.000) | |
| territory | No | Mainland Portugal (continente) or the Azores and Madeira (regioes_autonomas), which have their own IMT tables | continente |
| non_resident | No | The buyer is not and has never been tax resident in Portugal. IMT is then a flat rate with no exemption or reduction — no zero band, no young buyers' table, no stamp duty deduction (CIMT art. 17.º n.º 10); the result says what the Tax Authority annuls on request if the buyer becomes tax resident or lets the home at a moderate rent. A buyer who has already been treated as tax resident pays by the tables: leave it false | |
| primary_home | No | The buyer's own permanent home (habitação própria e permanente); false for a second home or an investment, which has no zero band | |
| buyer_is_young | No | The buyer is 35 or under on the date of the deed, is buying their first own permanent home, is not an IRS dependant and has owned no residential property in the previous three years. Applies the reduced IMT table and the stamp duty deduction (art. 7.º-A Código do Imposto do Selo; not applied above the second band of the young buyers' table). Only applies when primary_home is true; with primary_home false it is ignored | |
| tax_haven_company | No | The buyer is a company or other entity with its tax domicile in a country, territory or region on the Portuguese list of more favourable tax regimes, or controlled directly or indirectly by such an entity. IMT is then 10 % with no exemption or reduction (CIMT art. 17.º n.º 4), whether or not it is resident, and it overrides non_resident. Never true for an individual (n.º 7) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare the tool is read-only, idempotent, non-destructive, and closed-world. The description adds important behavioral context beyond annotations: taxes are charged on the higher of `value` and `vpt`, `buyer_is_young` applies only with `primary_home`, and the result explains what the Tax Authority annuls later for non-residents.
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?
The description is dense but front-loaded and each sentence carries useful information. It could be slightly more scannable, but it avoids filler and prioritizes the most important usage constraints.
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 the rich input schema, output schema, and annotations, the description covers the essential context: purpose, exclusions, precedence rules, and special conditions. Nothing critical for correct invocation 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 the schema documents each parameter. The description adds cross-parameter semantics that the schema does not fully capture: the precedence of `tax_haven_company` over `non_resident`, the condition that `buyer_is_young` only applies when `primary_home` is true, and the rule that both taxes are charged on the higher of `value` and `vpt`.
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: calculate IMT, stamp duty, and Casa Pronta registration for a Portuguese home purchase using 2026 tables. It explicitly distinguishes itself from sibling tools `imi_annual_cost` and `glossary_lookup`.
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 ('when asked what a home purchase in Portugal costs on top of the price') and when-not-to-use alternatives ('Do not use it for the yearly property tax ... or to define a term such as VPT'). It also explains key decision rules like `tax_haven_company` taking precedence over `non_resident`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
municipality_housing_pipelineHousing pipeline of one municipality: cases to completionsARead-onlyIdempotentInspect
Use this when one municipality's housing pipeline from licence to completion is needed: cases, INE licences and completions, units for sale. Do not use it for monthly building activity (construction_barometer). Periods differ by stage; unknown is null, not 0.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | Language of the page links and labels; the text summary and field names stay English. uk is accepted as ua. | en |
| municipality | Yes | Municipality name in any case, accents optional (Porto, Lisboa, Vila Nova de Gaia, Matosinhos; Lisbon and Oporto are accepted) or its four-digit code (1312). Close spellings are found; two matches return an `ambiguous` error with candidates |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare read-only, idempotent, closed-world, and non-destructive behavior. The description adds important data semantics beyond annotations: periods differ by stage, and unknown values are null rather than zero. This is valuable context, though it does not cover every possible behavioral nuance.
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?
The description is short, front-loaded with the primary use case, and every sentence serves a purpose: usage guidance, exclusion, and an important data caveat.
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 rich annotations, 100% schema coverage, an output schema, and only two parameters, the description provides enough context for correct invocation. It covers purpose, sibling exclusion, and key data behavior without needing to explain return values.
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 parameters are already well documented in the schema. The description does not add parameter-specific meaning beyond what the schema provides, which is acceptable given the high coverage.
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 resource and scope: one municipality's housing pipeline from licence to completion, including cases, INE licences, completions, and units for sale. It also explicitly distinguishes this from `construction_barometer`, making the tool's purpose clear against a sibling.
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 explicit when-to-use guidance and a clear when-not-to-use case, naming the alternative tool (`construction_barometer`) for monthly building activity. This is exactly the kind of routing information an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
municipality_statsKey figures for one Portuguese municipalityARead-onlyIdempotentInspect
Use this when the key figures of one of Portugal's 308 municipalities are needed, each with its source and date. They are the IMI rate and history, INE sale price per m² (actual sales), purchasing power, population, licensed dwellings, building cases, new builds. Do not use it to compare places (compare_municipalities), inside a city (where_to_live) or for monthly building (construction_barometer). A figure that is not published is null, not estimated. A name matching two municipalities is refused with candidates.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | Language of the page links and labels; the text summary and field names stay English. uk is accepted as ua. | en |
| municipality | Yes | Municipality name in any case, accents optional (Porto, Lisboa, Vila Nova de Gaia, Matosinhos; Lisbon and Oporto are accepted) or its four-digit code (1312). Close spellings are found; two matches return an `ambiguous` error with candidates |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/closed-world, so the safety profile is covered. The description adds real behavioral value beyond that: every figure carries its source and date, unpublished figures return null rather than estimates, and ambiguous names are refused with candidates. It omits nothing critical, though response shape 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?
Front-loaded with the when-to-use clause, followed by the field list, then the exclusions in a compact parenthetical list. Four sentences, no filler, each carrying distinct 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?
Output schema exists so return values need no explanation, annotations cover the safety profile, and parameters are fully documented. The description fills the remaining gaps an agent needs: field inventory, null-not-estimated policy, and error behavior on ambiguous names.
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 both parameters are fully documented in the schema, so the baseline is 3. The description adds marginal but genuine meaning by restating the ambiguity refusal behavior (candidates returned) and the fact field labels stay English regardless of the language parameter is schema-side. Slight edge over baseline.
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 (key figures for one Portuguese municipality) and enumerates the exact figures returned (IMI rate, INE sale price per m², purchasing power, population, etc.). That enumeration makes it immediately distinguishable from siblings like imi_rate or municipality_housing_pipeline.
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 'Use this when...' plus an explicit 'Do not use it to compare places (compare_municipalities), inside a city (where_to_live) or for monthly building (construction_barometer)'. Each exclusion names the sibling that covers that case, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
request_consultationPrepare a request to flatin.pt, a licensed estate agencyARead-onlyIdempotentInspect
Use this when the person wants flatin.pt (licensed estate agency, AMI 28163) to contact them about buying a new-build apartment in Portugal. Do not use it to send the request (submit_consultation) or for emails about new projects (subscribe_digest). mode=link returns the form link and the consent text; mode=prepare checks the details and returns a summary, the GDPR (RGPD) consent text and a confirmation_token. Nothing is sent.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Older name for places: one place. Merged with places, city first | |
| mode | No | link: only the form link and the consent text. prepare: check the details, get a summary, the consent text and a confirmation_token for submit_consultation; nothing is sent | link |
| name | No | The person's name | |
| No | Only if the person gives no phone | ||
| phone | No | Phone in international format. Preferred over email | |
| budget | No | Deprecated: use budget_max. Read as budget_max when budget_min and budget_max are both empty | |
| client | No | Optional. Your app's host or name: recorded as the request's source | |
| intent | No | Optional. visit and reserve only with a project on sale, notify only with a project not yet on sale | |
| places | No | Where the person wants to buy: municipalities in Portugal (Lisboa or Lisbon) or districts, most important first. At least one place, unless project is given (the project's municipality comes first then) | |
| channel | No | How the person wants to be contacted on that phone | |
| message | No | Optional. The person's own words | |
| project | No | Optional. Slug of the development the request is about: the slug field of search_newbuilds | |
| language | No | The person's language: the consent text, the emails and the page links come in it. Another value is refused, except in mode=link, which falls back to English. uk is accepted as ua. | en |
| typology | No | Optional. Bedroom counts wanted (T2 = two bedrooms) | |
| deal_type | No | Deprecated and ignored: every request is to buy | |
| budget_max | No | Optional. Upper end of the budget in whole euros; if lower than budget_min, the two are swapped | |
| budget_min | No | Optional. Lower end of the budget in whole euros | |
| budget_band | No | Deprecated: use budget_min and budget_max. An old band (0-250k, 250-400k, 400-600k, 600k+), read as its range when both are empty | |
| property_type | No | Deprecated and ignored: every request is for a new-build apartment | |
| preferred_time | No | Optional, with intent=visit: when suits the person |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false; the description reinforces this with "Nothing is sent" and discloses what each mode returns, including that the GDPR/RGPD consent text and a confirmation_token come back from prepare. That goes beyond the annotations by explaining the two-phase flow rather than just the safety profile. What it omits is failure behaviour — e.g. whether prepare rejects invalid details, or that language values outside the enum are refused (which is only in the 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?
Three sentences, front-loaded with the use case, then exclusions, then mode behaviour, and the key reassurance ("Nothing is sent") lands at the end where it is most likely to be read. 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 20-parameter tool with an output schema and zero required parameters, the description covers purpose, routing, mode branching and the no-side-effect guarantee. It stops short of hinting at the important non-obvious rules — phone preferred over email, places required unless project is supplied, deprecated fields to avoid — though those are documented in the 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 description coverage is 100% and 20 parameters are fully annotated, so the baseline is 3. The description adds real value only for `mode`, whose two branches it spells out in prose; the remaining parameters, including the deprecated budget/band/property_type aliases and the places-vs-project interaction, are left entirely to 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?
The description names a specific action (prepare a consultation request) against a named, licensed counterparty, and pins the object down to a new-build apartment purchase in Portugal. It explicitly distinguishes itself from the two nearest siblings, submit_consultation and subscribe_digest, so an agent can route correctly without opening a 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 opens with an explicit use condition ("Use this when the person wants flatin.pt to contact them"), then gives two explicit when-not cases naming the alternative tools. The mode split is also framed functionally: mode=link for just the link and consent, mode=prepare for validation plus a confirmation_token that gates submit_consultation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
required_incomeIncome and savings needed to buy a home at a priceARead-onlyIdempotentInspect
Use this when asked what net monthly income and savings it takes to buy a home in Portugal at a given price, under the Banco de Portugal rules. Do not use it for the purchase taxes alone (imt_calculate).
| Name | Required | Description | Default |
|---|---|---|---|
| price | Yes | Price of the home in euros; a dot or a space may group thousands (250.000). Fixed scenario: buyer aged 30, own permanent home, 40-year loan, 10 % deposit, IMT Jovem, market rate | |
| territory | No | Mainland Portugal (continente) or the Azores and Madeira (regioes_autonomas), which have their own IMT tables | continente |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so the safety profile is covered. The description adds no extra behavioral context such as the fixed buyer scenario assumptions or how results are derived, leaving that to the schema. Adequate but not additive.
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?
Two sentences, no wasted words, with the positive trigger front-loaded and the exclusion following immediately. Ideal sizing for a narrow calculation 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?
An output schema exists and the input schema fully documents the fixed scenario assumptions, so an agent has what it needs to call it correctly. The description alone would not reveal those assumptions, which keeps it from a 5.
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 parameter descriptions already explain the price format, the fixed scenario (age 30, 40-year loan, 10% deposit, IMT Jovem, market rate) and the territory enum. The description contributes nothing beyond this, so the 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 concrete computation (net monthly income and savings needed) tied to a specific resource and jurisdiction (a home in Portugal at a given price, under Banco de Portugal rules). This is clearly distinguishable from the sibling `imt_calculate`.
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 ('when asked what net monthly income and savings it takes') and an explicit exclusion naming the alternative tool to use for purchase taxes alone ('Do not use it for... `imt_calculate`'). Routing is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_newbuildsSearch new-build projects in PortugalARead-onlyIdempotentInspect
Use this when the person wants to find published new-build projects (empreendimentos) in Portugal on flatin.pt. Do not use it for one project's details (get_newbuild with its slug) or for how much is being built (construction_barometer). With typology, the budget applies to those typologies' prices; projects without a published price drop out when a budget is given. Pass next_offset as offset for the next page. A misspelt filter is refused, not ignored. Prices are as checked on developers' pages or agency listings, dated.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | price: cheapest first; delivery: soonest first; new: recently added first. Projects with a price always come before those without | price |
| limit | No | Results per call | |
| stage | No | Construction stage: planned, licensed, building (under construction), selling (on sale), delivered (completed) | |
| offset | No | Skip this many results: pass next_offset from the previous answer | |
| parish | No | Parish (freguesia) name. Exact name, accents optional | |
| on_sale | No | Only projects with a published price | |
| language | No | Language of the page URLs and of the labels (stage, typology, nearby places); the text summary shows the typology labels in it. Field names stay English. uk is accepted as ua. | en |
| typology | No | Bedrooms: T0 studio … T5 (five or more). Any of the listed matches | |
| price_max | No | Budget upper bound in euros, e.g. 350000. With typology, the budget applies to those typologies' prices. Projects with no published price are left out when a budget is given | |
| price_min | No | Budget lower bound in euros | |
| delivery_by | No | Completed, or promised for this year or earlier (overdue promises included), e.g. 2027; at most five years back. Projects with no announced date are left out | |
| energy_class | No | Energy certificate class of at least one unit, as stated by the source. Often not published: filter only when asked | |
| municipality | No | City / municipality (concelho): name, slug or four-digit code, e.g. Porto, Lisboa, Vila Nova de Gaia, Matosinhos, 1312. English names (Lisbon) and accents-free spelling are understood; an ambiguous name (Lagoa) is refused with candidates |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this a safe, idempotent, closed-world read, so the bar is lower. The description still adds real behavioral context the annotations don't: misspelt filters are refused rather than ignored, projects without a published price silently drop out when a budget is given, and prices are dated from developers/agency sources. It doesn't discuss result cardinality beyond pagination, but the output schema covers return shape.
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?
Five short sentences, front-loaded with the routing decision and exclusions before any filtering nuance. Every sentence carries distinct information — no restatement of the name or title.
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 search with zero required params, an output schema and full annotations, the description supplies exactly the missing layer: sibling routing, the price/typology interaction, typo-refusal behavior, and pagination handoff. An agent has enough to call it correctly on the first attempt.
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 baseline would be 3; the description earns above that by explaining a genuine cross-parameter interaction ('with typology, the budget applies to those typologies' prices') and the silent exclusion it triggers, which the schema only states per-property. It also bridges the pagination contract by telling the agent to pass next_offset as offset, linking the request to the response.
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 ('find published new-build projects (empreendimentos) in Portugal on flatin.pt') and immediately pins down scope against the two nearest siblings. An agent can distinguish this from get_newbuild and construction_barometer without opening a 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 clause plus explicit when-not-to-use with the named alternatives and the condition that selects each ('one project's details' → get_newbuild with its slug; 'how much is being built' → construction_barometer). Nothing 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.
submit_consultationSend a prepared request to flatin.ptADestructiveIdempotentInspect
Use this when the person has read the summary and consent text from request_consultation mode=prepare and explicitly agreed to send the request. Do not use it before that (request_consultation). Pass the same details, the token, consent=true and consent_text_version; never set consent=true on your own. Changed details, a token under 5 seconds or over 30 minutes old, or an outdated consent version are refused.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | As in prepare | |
| name | No | As in prepare | |
| No | As in prepare | ||
| phone | No | As in prepare | |
| budget | No | As in prepare | |
| client | No | As in prepare | |
| intent | No | As in prepare | |
| places | No | As in prepare | |
| channel | No | As in prepare | |
| consent | Yes | true once the person has read the consent text returned by mode=prepare and explicitly agreed | |
| message | No | As in prepare | |
| project | No | As in prepare | |
| language | No | As in prepare | en |
| typology | No | As in prepare | |
| deal_type | No | As in prepare | |
| budget_max | No | As in prepare | |
| budget_min | No | As in prepare | |
| budget_band | No | As in prepare | |
| property_type | No | As in prepare | |
| preferred_time | No | As in prepare | |
| confirmation_token | Yes | The token returned by request_consultation mode=prepare | |
| consent_text_version | Yes | consent_text_version returned by mode=prepare |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses critical behavioral constraints: the confirmation token must be 5 seconds to 30 minutes old, changed details are refused, outdated consent versions are refused, and the agent must not set consent=true on its own. These are material operational details that directly affect correct invocation.
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 usage condition and negative case, then the required parameter behavior, then refusal conditions. Every sentence contributes necessary guidance with no 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?
Given the high parameter count, the existence of an output schema, and the sensitive consent workflow, the description covers the essential prerequisites, token lifetime, consent handling, and refusal cases. Return values need not be described because an output schema exists.
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 meaningful semantics for the key submission parameters: pass the same details, the token, `consent=true`, and `consent_text_version`, and never fabricate consent. It does not document every one of the 22 parameters, but the schema already covers them.
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 action: sending a prepared request to flatin.pt after prior consent. It clearly distinguishes this submission step from the sibling `request_consultation` preparation step, so an agent can identify its purpose without inspecting 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 explicitly says when to use it: after the person has read the summary and consent text from `request_consultation` mode=prepare and explicitly agreed. It also explicitly says when not to use it and names the prerequisite tool, leaving no ambiguity about sequencing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
subscribe_digestSubscribe an email to new developments or constructionAIdempotentInspect
Use this when the person asks to be emailed about new-build projects matching a filter (daily) or new construction licensed in one municipality (weekly). Do not use it to have flatin.pt contact them (request_consultation) or to see what is on sale now (search_newbuilds). Ask the person first; nothing is active until they click the confirmation email. city is required for construction and parish works only there; typology, the prices and on_sale work only with new_developments. The answer is the same whether or not the address was already subscribed: never say it was.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Municipality (Lisboa or Lisbon). Required for construction; empty means all of Portugal for new_developments | |
| what | No | new_developments: new-build developments matching the filter, daily email when something new appears. construction: newly licensed construction in a municipality ("what is being built"), weekly | new_developments |
| Yes | The person's email address | ||
| client | No | Optional. Your app's host or name: recorded as the request's source | |
| parish | No | Optional, construction only: a parish (freguesia) of that municipality | |
| on_sale | No | Optional, new_developments: only developments on sale | |
| language | No | The person's language: the consent text and the emails come in it. uk is accepted as ua. | en |
| typology | No | Optional. Bedroom counts wanted (T2 = two bedrooms) | |
| price_max | No | Optional, new_developments: maximum price in euros | |
| price_min | No | Optional, new_developments: minimum price in euros |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds real behavioral context beyond the annotations: double opt-in ("nothing is active until they click the confirmation email") and the deliberate ambiguity of the response ("never say it was already subscribed"), which pairs with idempotentHint=true. The annotations already cover safety (destructive=false, readOnly=false, openWorld=true), so this addition is the valuable part; it could go further on whether an existing subscription can be cancelled or modified later.
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 usage condition, then exclusions, then consent behavior, then parameter constraints — a sensible ordering with no filler sentences. It is dense to the point of being packed with semicolons, but every clause carries distinct 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 10-parameter mutation tool with an output schema (so return values need no explanation), the description covers the missing pieces: mode-conditional parameters, consent flow, and post-call phrasing. An agent can call this correctly and report the result appropriately from the description 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 coverage is 100%, so the baseline is 3; the description earns an extra point by consolidating the cross-parameter conditional logic that the schema only states piecemeal — `city` required for construction, `parish` construction-only, `typology`/prices/`on_sale` new-developments-only. It restates some of what individual property descriptions already say, so it is not fully additive.
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: subscribing an email address to a digest, with the two modes (daily new-build developments vs weekly licensed construction) spelled out. It explicitly names what it is not (`request_consultation`, `search_newbuilds`), so an agent can separate it from those siblings without opening their 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?
Gives an explicit trigger ("when the person asks to be emailed about..."), explicit exclusions with the correct alternative tool named for each, and a procedural prerequisite ("Ask the person first"). Nothing about tool selection 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.
where_to_liveWhere to live in a Portuguese city, area by areaARead-onlyIdempotentInspect
Use this when the person is choosing a neighbourhood: a flatin.pt city guide's verdict area by area, with the reason, who each area suits and the sources. Do not use it for one municipality's figures (municipality_stats) or for new homes there (search_newbuilds). Without city it lists the cities and regions that have a guide. profile narrows the areas but never hides the ones we advise against. Noise and safety come as dated, sourced facts: a place's reputation, never a claim about its people. Show the guide's link to the user.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | City or region with a guide, in any site language (Porto, Lisbon, Lisboa, Greater Porto, Algarve, Coimbra) or a municipality inside a guide (Gaia, Cascais, Faro). Omit to list the guides | |
| include | No | Parts of the guide to return; all returns every section | |
| profile | No | Keep the areas that suit this profile; profile never removes the areas we advise against | |
| verdict | No | Keep only areas with this verdict: live (good to live), depends (depends on you), avoid (we advise against) | |
| language | No | Language of the answer: the guide or the definition, the text summary and the page links. Field names stay English. uk is accepted as ua. | en |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish the read-only, non-destructive, idempotent profile. The description adds useful behavioral context beyond that: listing cities when `city` is omitted, preserving advised-against areas under `profile`, treating noise and safety as dated sourced facts rather than claims about people, and instructing the agent to show the guide link. It does not add much about return shape, but the output schema exists.
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?
The description is dense but front-loaded: it opens with the use case, immediately states exclusions and alternatives, then covers edge cases and behavioral nuances. Every sentence contributes routing or behavioral guidance.
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 the rich annotations, full schema coverage, and output schema, the description provides everything an agent needs: purpose, alternatives, edge-case behavior, profile semantics, sourcing stance, and link handling. No material gap remains for correct selection or invocation.
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 all five parameters thoroughly. The description reinforces a few behaviors such as the omitted-`city` fallback and `profile` preservation, but does not add meaning beyond what the schema already states.
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 decision context (choosing a neighbourhood) and a concrete resource (flatin.pt city guide's area-by-area verdicts, reasons, suitability, and sources). It also distinguishes the tool from `municipality_stats` and `search_newbuilds`, so an agent can identify its role without opening sibling 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?
It explicitly says when to use the tool and when not to use it, naming the two sibling alternatives for the excluded cases. It also explains the no-`city` fallback, giving an agent clear routing guidance.
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.
2 tool updates
- Changed
request_consultation6 fields changed- removed
Input schema / properties / confirmation_tokenRemoved value: -{ - "description": "submit only: the token returned by prepare", - "type": "string" -} - removed
Input schema / properties / consentRemoved value: -{ - "description": "submit only: true once the person has read the consent text returned by prepare and explicitly agreed", - "type": "boolean" -} - removed
Input schema / properties / consent_text_versionRemoved value: -{ - "description": "submit only: consent_text_version returned by prepare", - "type": "string" -} - changed
Input schema / properties / mode / descriptionPrevious value: -"link: only the form link and the consent text. prepare: check the details, get a summary, the consent text and a confirmation_token; nothing is sent. submit: send the request — the same details as in prepare plus confirmation_token, consent=true and consent_text_version, only after the person has read the consent text and explicitly agreed"New value: +"link: only the form link and the consent text. prepare: check the details, get a summary, the consent text and a confirmation_token for submit_consultation; nothing is sent" - changed
Input schema / properties / mode / enumPrevious value: -[ - "link", - "prepare", - "submit" -]New value: +[ + "link", + "prepare" +] - changed
Output schema / anyOfPrevious value: -[ - { - "description": "mode=link: the form link and the consent text; nothing is sent.", - "properties": { - "attribution": { - "type": "object" - }, - "consent_language": { - "type": "string" - }, - "consent_text": { - "type": "string" - }, - "consent_text_version": { - "type": "string" - }, - "consent_version": { - "description": "Same as consent_text_version", - "type": "string" - }, - "form_url": { - "description": "Absolute URL", - "type": "string" - }, - "language": { - "type": "string" - }, - "mode": { - "type": "string" - }, - "what_happens_next": { - "type": "string" - } - }, - "required": [ - "mode", - "form_url", - "consent_text", - "consent_text_version", - "consent_language", - "consent_version", - "what_happens_next", - "language", - "attribution" - ], - "type": "object" - }, - { - "description": "mode=prepare: summary, consent text and token; nothing is sent.", - "properties": { - "confirmation_token": { - "type": "string" - }, - "consent_language": { - "type": "string" - }, - "consent_text": { - "type": "string" - }, - "consent_text_version": { - "type": "string" - }, - "expires_in_seconds": { - "type": "integer" - }, - "mode": { - "type": "string" - }, - "summary": { - "type": "object" - }, - "what_happens_next": { - "type": "string" - } - }, - "required": [ - "mode", - "summary", - "consent_text", - "consent_text_version", - "consent_language", - "confirmation_token", - "expires_in_seconds", - "what_happens_next" - ], - "type": "object" - }, - { - "description": "mode=submit: the request was received; flatin.pt answers it.", - "properties": { - "mode": { - "type": "string" - }, - "privacy_policy": { - "description": "Absolute URL", - "type": "string" - }, - "status": { - "type": "string" - }, - "what_happens_next": { - "type": "string" - } - }, - "required": [ - "mode", - "status", - "what_happens_next", - "privacy_policy" - ], - "type": "object" - }, - { - "properties": { - "consent_language": { - "type": "string" - }, - "consent_text": { - "type": "string" - }, - "consent_text_version": { - "type": "string" - }, - "error": { - "type": "string" - }, - "field": { - "type": [ - "string", - "null" - ] - }, - "message": { - "type": "string" - }, - "problems": { - "items": { - "type": "object" - }, - "type": "array" - }, - "retry_after_seconds": { - "type": "integer" - } - }, - "required": [ - "error", - "message" - ], - "type": "object" - } -]New value: +[ + { + "description": "mode=link: the form link and the consent text; nothing is sent.", + "properties": { + "attribution": { + "type": "object" + }, + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "consent_version": { + "description": "Same as consent_text_version", + "type": "string" + }, + "form_url": { + "description": "Absolute URL", + "type": "string" + }, + "language": { + "type": "string" + }, + "mode": { + "type": "string" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "form_url", + "consent_text", + "consent_text_version", + "consent_language", + "consent_version", + "what_happens_next", + "language", + "attribution" + ], + "type": "object" + }, + { + "description": "mode=prepare: summary, consent text and token; nothing is sent.", + "properties": { + "confirmation_token": { + "type": "string" + }, + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "expires_in_seconds": { + "type": "integer" + }, + "mode": { + "type": "string" + }, + "summary": { + "type": "object" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "summary", + "consent_text", + "consent_text_version", + "consent_language", + "confirmation_token", + "expires_in_seconds", + "what_happens_next" + ], + "type": "object" + }, + { + "properties": { + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + }, + "problems": { + "items": { + "type": "object" + }, + "type": "array" + }, + "retry_after_seconds": { + "type": "integer" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } +]
- Added
submit_consultation
2 tool updates
- Changed
municipality_stats1 field changed- changed
Output schema / anyOfPrevious value: -[ - { - "properties": { - "attribution": { - "type": "object" - }, - "construction_barometer": { - "type": [ - "object", - "null" - ] - }, - "imi": { - "type": "object" - }, - "language": { - "type": "string" - }, - "licensed_buildings_all_works": { - "type": [ - "object", - "null" - ] - }, - "licensed_new_buildings": { - "type": [ - "object", - "null" - ] - }, - "licensed_new_dwellings": { - "type": [ - "object", - "null" - ] - }, - "municipal_cases": { - "type": [ - "object", - "null" - ] - }, - "municipality": { - "type": "object" - }, - "new_builds": { - "type": "object" - }, - "population": { - "type": [ - "object", - "null" - ] - }, - "purchasing_power": { - "description": "Index, Portugal = 100", - "type": [ - "object", - "null" - ] - }, - "sale_prices": { - "type": [ - "object", - "null" - ] - }, - "url": { - "description": "Absolute URL or null", - "type": [ - "string", - "null" - ] - }, - "where_to_live": { - "items": { - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "municipality", - "url", - "imi", - "sale_prices", - "purchasing_power", - "population", - "licensed_new_dwellings", - "licensed_new_buildings", - "licensed_buildings_all_works", - "municipal_cases", - "construction_barometer", - "new_builds", - "where_to_live", - "attribution", - "language" - ], - "type": "object" - }, - { - "properties": { - "candidates": { - "items": { - "type": "object" - }, - "type": "array" - }, - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "suggestions": { - "items": { - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "error", - "message" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "affordability": { + "type": [ + "object", + "null" + ] + }, + "attribution": { + "type": "object" + }, + "construction_barometer": { + "type": [ + "object", + "null" + ] + }, + "imi": { + "type": "object" + }, + "language": { + "type": "string" + }, + "licensed_buildings_all_works": { + "type": [ + "object", + "null" + ] + }, + "licensed_new_buildings": { + "type": [ + "object", + "null" + ] + }, + "licensed_new_dwellings": { + "type": [ + "object", + "null" + ] + }, + "municipal_cases": { + "type": [ + "object", + "null" + ] + }, + "municipality": { + "type": "object" + }, + "new_builds": { + "type": "object" + }, + "population": { + "type": [ + "object", + "null" + ] + }, + "purchasing_power": { + "description": "Index, Portugal = 100", + "type": [ + "object", + "null" + ] + }, + "sale_prices": { + "type": [ + "object", + "null" + ] + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "where_to_live": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "municipality", + "url", + "imi", + "sale_prices", + "purchasing_power", + "population", + "licensed_new_dwellings", + "licensed_new_buildings", + "licensed_buildings_all_works", + "municipal_cases", + "construction_barometer", + "new_builds", + "where_to_live", + "attribution", + "language" + ], + "type": "object" + }, + { + "properties": { + "candidates": { + "items": { + "type": "object" + }, + "type": "array" + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "suggestions": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } +]
- Added
required_income
1 tool update
- Changed
municipality_housing_pipeline1 field changed- changed
Output schema / anyOfPrevious value: -[ - { - "description": "One municipality: every stage with its own period and source.", - "properties": { - "attribution": { - "type": "object" - }, - "caveat": { - "type": "string" - }, - "coverage": { - "type": "object" - }, - "language": { - "type": "string" - }, - "method_url": { - "description": "Absolute URL or null", - "type": [ - "string", - "null" - ] - }, - "municipality": { - "type": "object" - }, - "municipality_url": { - "description": "Absolute URL or null", - "type": [ - "string", - "null" - ] - }, - "ratio_completed_licensed": { - "type": "object" - }, - "stages": { - "items": { - "type": "object" - }, - "type": "array" - }, - "url": { - "description": "Absolute URL or null", - "type": [ - "string", - "null" - ] - } - }, - "required": [ - "language", - "municipality", - "coverage", - "stages", - "ratio_completed_licensed", - "caveat", - "url", - "method_url", - "municipality_url", - "attribution" - ], - "type": "object" - }, - { - "properties": { - "candidates": { - "items": { - "type": "object" - }, - "type": "array" - }, - "error": { - "type": "string" - }, - "message": { - "type": "string" - }, - "suggestions": { - "items": { - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "error", - "message" - ], - "type": "object" - } -]New value: +[ + { + "description": "One municipality: every stage with its own period and source.", + "properties": { + "attribution": { + "type": "object" + }, + "caveat": { + "type": "string" + }, + "coverage": { + "type": "object" + }, + "durations": { + "description": "Age of licensing cases in progress (an age, not a processing time).", + "type": "object" + }, + "language": { + "type": "string" + }, + "method_url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "municipality": { + "type": "object" + }, + "municipality_url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "ratio_completed_licensed": { + "type": "object" + }, + "stages": { + "items": { + "type": "object" + }, + "type": "array" + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "language", + "municipality", + "coverage", + "stages", + "ratio_completed_licensed", + "durations", + "caveat", + "url", + "method_url", + "municipality_url", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "candidates": { + "items": { + "type": "object" + }, + "type": "array" + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "suggestions": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } +]
1 tool update
- Added
municipality_housing_pipeline
1 tool update
- Changed
get_newbuild1 field changed- changed
Output schema / anyOfPrevious value: -[ - { - "properties": { - "area": { - "type": [ - "object", - "null" - ] - }, - "attribution": { - "type": "object" - }, - "checked_on": { - "description": "Date, YYYY-MM-DD", - "type": "string" - }, - "delivery": { - "type": "object" - }, - "developer": { - "type": "object" - }, - "image": { - "description": "Absolute URL or null", - "type": [ - "string", - "null" - ] - }, - "language": { - "type": "string" - }, - "location": { - "type": [ - "object", - "null" - ] - }, - "location_precision": { - "type": "string" - }, - "municipality": { - "type": "object" - }, - "name": { - "type": "string" - }, - "nearby": { - "type": [ - "object", - "null" - ] - }, - "parish": { - "type": [ - "string", - "null" - ] - }, - "permits": { - "items": { - "type": "object" - }, - "type": "array" - }, - "price": { - "type": "object" - }, - "purchase_cost": { - "type": [ - "object", - "null" - ] - }, - "slug": { - "type": "string" - }, - "stage": { - "type": "object" - }, - "summary": { - "type": [ - "string", - "null" - ] - }, - "typologies": { - "items": { - "type": "object" - }, - "type": "array" - }, - "updated_on": { - "description": "Date, YYYY-MM-DD", - "type": "string" - }, - "url": { - "description": "Absolute URL", - "type": "string" - }, - "urls": { - "type": "object" - } - }, - "required": [ - "slug", - "name", - "url", - "urls", - "language", - "summary", - "developer", - "municipality", - "parish", - "stage", - "delivery", - "price", - "typologies", - "purchase_cost", - "permits", - "location", - "location_precision", - "area", - "nearby", - "image", - "checked_on", - "updated_on", - "attribution" - ], - "type": "object" - }, - { - "properties": { - "error": { - "type": "string" - }, - "field": { - "type": [ - "string", - "null" - ] - }, - "message": { - "type": "string" - } - }, - "required": [ - "error", - "message" - ], - "type": "object" - } -]New value: +[ + { + "properties": { + "area": { + "type": [ + "object", + "null" + ] + }, + "attribution": { + "type": "object" + }, + "checked_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "delivery": { + "type": "object" + }, + "developer": { + "description": "null when the developer is not confirmed", + "type": [ + "object", + "null" + ] + }, + "image": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "language": { + "type": "string" + }, + "location": { + "type": [ + "object", + "null" + ] + }, + "location_precision": { + "type": "string" + }, + "municipality": { + "type": "object" + }, + "name": { + "type": "string" + }, + "nearby": { + "type": [ + "object", + "null" + ] + }, + "parish": { + "type": [ + "string", + "null" + ] + }, + "permits": { + "items": { + "type": "object" + }, + "type": "array" + }, + "price": { + "type": "object" + }, + "purchase_cost": { + "type": [ + "object", + "null" + ] + }, + "slug": { + "type": "string" + }, + "stage": { + "type": "object" + }, + "summary": { + "type": [ + "string", + "null" + ] + }, + "typologies": { + "items": { + "type": "object" + }, + "type": "array" + }, + "updated_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "url": { + "description": "Absolute URL", + "type": "string" + }, + "urls": { + "type": "object" + } + }, + "required": [ + "slug", + "name", + "url", + "urls", + "language", + "summary", + "developer", + "municipality", + "parish", + "stage", + "delivery", + "price", + "typologies", + "purchase_cost", + "permits", + "location", + "location_precision", + "area", + "nearby", + "image", + "checked_on", + "updated_on", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } +]
1 tool update
- Changed
request_consultation17 fields changed- added
Input schema / properties / budget / deprecatedAdded value: +true - changed
Input schema / properties / budget / descriptionPrevious value: -"Optional. Budget in whole euros, e.g. 350000"New value: +"Deprecated: use budget_max. Read as budget_max when budget_min and budget_max are both empty" - added
Input schema / properties / budget_bandAdded value: +{ + "deprecated": true, + "description": "Deprecated: use budget_min and budget_max. An old band (0-250k, 250-400k, 400-600k, 600k+), read as its range when both are empty", + "examples": [ + "250-400k" + ], + "type": "string" +} - added
Input schema / properties / budget_maxAdded value: +{ + "description": "Optional. Upper end of the budget in whole euros; if lower than budget_min, the two are swapped", + "examples": [ + 400000 + ], + "type": "integer" +} - added
Input schema / properties / budget_minAdded value: +{ + "description": "Optional. Lower end of the budget in whole euros", + "examples": [ + 250000 + ], + "type": "integer" +} - changed
Input schema / properties / city / descriptionPrevious value: -"Municipality in Portugal (Lisboa or Lisbon) or a district. Not needed with project, which sets the place"New value: +"Older name for places: one place. Merged with places, city first" - changed
Input schema / properties / city / examplesPrevious value: -[ - "Porto", - "Matosinhos" -]New value: +[ + "Porto" +] - removed
Input schema / properties / deal_type / defaultRemoved value: -"buy" - added
Input schema / properties / deal_type / deprecatedAdded value: +true - changed
Input schema / properties / deal_type / descriptionPrevious value: -"Renting is not handled"New value: +"Deprecated and ignored: every request is to buy" - removed
Input schema / properties / deal_type / enumRemoved value: -[ - "buy", - "sell" -] - added
Input schema / properties / deal_type / examplesAdded value: +[ + "buy" +] - added
Input schema / properties / placesAdded value: +{ + "description": "Where the person wants to buy: municipalities in Portugal (Lisboa or Lisbon) or districts, most important first. At least one place, unless project is given (the project's municipality comes first then)", + "examples": [ + [ + "Porto", + "Matosinhos" + ] + ], + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / property_type / deprecatedAdded value: +true - changed
Input schema / properties / property_type / descriptionPrevious value: -"apartment if not given, or new_build when project is given"New value: +"Deprecated and ignored: every request is for a new-build apartment" - removed
Input schema / properties / property_type / enumRemoved value: -[ - "apartment", - "house", - "commercial", - "new_build" -] - added
Input schema / properties / property_type / examplesAdded value: +[ + "apartment" +]
1 tool update
- Changed
request_consultation1 field changed- changed
Output schema / anyOfPrevious value: -[ - { - "description": "mode=link: the form link and the consent text; nothing is sent.", - "properties": { - "attribution": { - "type": "object" - }, - "consent_language": { - "type": "string" - }, - "consent_text": { - "type": "string" - }, - "consent_text_version": { - "type": "string" - }, - "consent_version": { - "description": "Same as consent_text_version", - "type": "string" - }, - "form_url": { - "description": "Absolute URL", - "type": "string" - }, - "language": { - "type": "string" - }, - "mode": { - "type": "string" - }, - "what_happens_next": { - "type": "string" - } - }, - "required": [ - "mode", - "form_url", - "consent_text", - "consent_text_version", - "consent_language", - "consent_version", - "what_happens_next", - "language", - "attribution" - ], - "type": "object" - }, - { - "description": "mode=prepare: summary, consent text and token; nothing is sent.", - "properties": { - "confirmation_token": { - "type": "string" - }, - "consent_language": { - "type": "string" - }, - "consent_text": { - "type": "string" - }, - "consent_text_version": { - "type": "string" - }, - "expires_in_seconds": { - "type": "integer" - }, - "mode": { - "type": "string" - }, - "summary": { - "type": "object" - }, - "what_happens_next": { - "type": "string" - } - }, - "required": [ - "mode", - "summary", - "consent_text", - "consent_text_version", - "consent_language", - "confirmation_token", - "expires_in_seconds", - "what_happens_next" - ], - "type": "object" - }, - { - "description": "mode=submit: the request was received and passed on.", - "properties": { - "mode": { - "type": "string" - }, - "privacy_policy": { - "description": "Absolute URL", - "type": "string" - }, - "status": { - "type": "string" - }, - "what_happens_next": { - "type": "string" - } - }, - "required": [ - "mode", - "status", - "what_happens_next", - "privacy_policy" - ], - "type": "object" - }, - { - "properties": { - "consent_language": { - "type": "string" - }, - "consent_text": { - "type": "string" - }, - "consent_text_version": { - "type": "string" - }, - "error": { - "type": "string" - }, - "field": { - "type": [ - "string", - "null" - ] - }, - "message": { - "type": "string" - }, - "problems": { - "items": { - "type": "object" - }, - "type": "array" - }, - "retry_after_seconds": { - "type": "integer" - } - }, - "required": [ - "error", - "message" - ], - "type": "object" - } -]New value: +[ + { + "description": "mode=link: the form link and the consent text; nothing is sent.", + "properties": { + "attribution": { + "type": "object" + }, + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "consent_version": { + "description": "Same as consent_text_version", + "type": "string" + }, + "form_url": { + "description": "Absolute URL", + "type": "string" + }, + "language": { + "type": "string" + }, + "mode": { + "type": "string" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "form_url", + "consent_text", + "consent_text_version", + "consent_language", + "consent_version", + "what_happens_next", + "language", + "attribution" + ], + "type": "object" + }, + { + "description": "mode=prepare: summary, consent text and token; nothing is sent.", + "properties": { + "confirmation_token": { + "type": "string" + }, + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "expires_in_seconds": { + "type": "integer" + }, + "mode": { + "type": "string" + }, + "summary": { + "type": "object" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "summary", + "consent_text", + "consent_text_version", + "consent_language", + "confirmation_token", + "expires_in_seconds", + "what_happens_next" + ], + "type": "object" + }, + { + "description": "mode=submit: the request was received; flatin.pt answers it.", + "properties": { + "mode": { + "type": "string" + }, + "privacy_policy": { + "description": "Absolute URL", + "type": "string" + }, + "status": { + "type": "string" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "status", + "what_happens_next", + "privacy_policy" + ], + "type": "object" + }, + { + "properties": { + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + }, + "problems": { + "items": { + "type": "object" + }, + "type": "array" + }, + "retry_after_seconds": { + "type": "integer" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } +]
12 tool updates
- Changed
compare_municipalities2 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en"New value: +"Language of the page links and labels; the text summary and field names stay English. uk is accepted as ua." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "attribution": { + "type": "object" + }, + "language": { + "type": "string" + }, + "municipalities": { + "items": { + "type": "object" + }, + "type": "array" + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "language", + "municipalities", + "url", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "candidates": { + "items": { + "type": "object" + }, + "type": "array" + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "suggestions": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
construction_barometer6 fields changed- added
Input schema / properties / granularity / defaultAdded value: +"month" - changed
Input schema / properties / granularity / descriptionPrevious value: -"Period of our own series. Default: month"New value: +"Period of our own series; the INE series is yearly either way" - changed
Input schema / properties / language / descriptionPrevious value: -"Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en"New value: +"Language of the page links and labels; the text summary and field names stay English. uk is accepted as ua." - added
Input schema / properties / measure / defaultAdded value: +"total_works" - changed
Input schema / properties / measure / descriptionPrevious value: -"Kind of works: total_works (default), new_build, alter_extend"New value: +"Kind of works counted in our own series: all works, new buildings, or alterations and extensions" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "description": "Without municipality: every municipality we collect, and the index.", + "properties": { + "attribution": { + "type": "object" + }, + "caveat": { + "type": "string" + }, + "language": { + "type": "string" + }, + "measure": { + "type": "string" + }, + "method_url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "municipalities": { + "items": { + "type": "object" + }, + "type": "array" + }, + "panel_index": { + "type": "object" + }, + "snapshot": { + "description": "Date, YYYY-MM-DD, or null", + "type": [ + "string", + "null" + ] + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "window": { + "type": "object" + } + }, + "required": [ + "language", + "measure", + "snapshot", + "window", + "municipalities", + "panel_index", + "caveat", + "url", + "method_url", + "attribution" + ], + "type": "object" + }, + { + "description": "With municipality: our series (if collected) and INE's yearly series.", + "properties": { + "attribution": { + "type": "object" + }, + "caveat": { + "type": "string" + }, + "covered_municipalities": { + "items": { + "type": "object" + }, + "type": "array" + }, + "granularity": { + "type": "string" + }, + "in_own_series": { + "type": "boolean" + }, + "ine_official": { + "type": "object" + }, + "language": { + "type": "string" + }, + "measure": { + "type": "string" + }, + "method_url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "municipality": { + "type": "object" + }, + "municipality_url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "own_series": { + "items": { + "type": "object" + }, + "type": "array" + }, + "snapshot": { + "description": "Date, YYYY-MM-DD, or null", + "type": [ + "string", + "null" + ] + }, + "summary": { + "type": [ + "object", + "null" + ] + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "language", + "municipality", + "measure", + "granularity", + "snapshot", + "in_own_series", + "own_series", + "summary", + "ine_official", + "covered_municipalities", + "caveat", + "url", + "method_url", + "municipality_url", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "candidates": { + "items": { + "type": "object" + }, + "type": "array" + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "suggestions": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
get_newbuild9 fields changed- added
Input schema / properties / buyer_is_young / defaultAdded value: +false - changed
Input schema / properties / buyer_is_young / descriptionPrevious value: -"For the purchase cost: buyer aged 35 or under, first own home (reduced IMT and stamp duty relief). Default false"New value: +"For the purchase cost only: buyer aged 35 or under, first own home (reduced IMT and stamp duty relief); applies only with primary_home" - added
Input schema / properties / language / defaultAdded value: +"en" - changed
Input schema / properties / language / descriptionPrevious value: -"Language of the page URLs and labels: pt, en, ru, ua, de, fr, nl. Default en"New value: +"Language of the page URLs and of the labels (stage, typology, nearby places); the text summary shows the typology labels in it. Field names stay English. uk is accepted as ua." - changed
Input schema / properties / language / enumPrevious value: -[ - "pt", - "en", - "ru", - "ua", - "de", - "fr", - "nl" -]New value: +[ + "pt", + "en", + "ru", + "ua", + "de", + "fr", + "nl", + "uk" +] - added
Input schema / properties / primary_home / defaultAdded value: +true - changed
Input schema / properties / primary_home / descriptionPrevious value: -"For the purchase cost: the buyer's own permanent home (habitação própria e permanente). Default true"New value: +"For the purchase cost only: the buyer's own permanent home (habitação própria e permanente)" - added
Input schema / properties / slug / minLengthAdded value: +1 - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "area": { + "type": [ + "object", + "null" + ] + }, + "attribution": { + "type": "object" + }, + "checked_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "delivery": { + "type": "object" + }, + "developer": { + "type": "object" + }, + "image": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "language": { + "type": "string" + }, + "location": { + "type": [ + "object", + "null" + ] + }, + "location_precision": { + "type": "string" + }, + "municipality": { + "type": "object" + }, + "name": { + "type": "string" + }, + "nearby": { + "type": [ + "object", + "null" + ] + }, + "parish": { + "type": [ + "string", + "null" + ] + }, + "permits": { + "items": { + "type": "object" + }, + "type": "array" + }, + "price": { + "type": "object" + }, + "purchase_cost": { + "type": [ + "object", + "null" + ] + }, + "slug": { + "type": "string" + }, + "stage": { + "type": "object" + }, + "summary": { + "type": [ + "string", + "null" + ] + }, + "typologies": { + "items": { + "type": "object" + }, + "type": "array" + }, + "updated_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "url": { + "description": "Absolute URL", + "type": "string" + }, + "urls": { + "type": "object" + } + }, + "required": [ + "slug", + "name", + "url", + "urls", + "language", + "summary", + "developer", + "municipality", + "parish", + "stage", + "delivery", + "price", + "typologies", + "purchase_cost", + "permits", + "location", + "location_precision", + "area", + "nearby", + "image", + "checked_on", + "updated_on", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
glossary_lookup2 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en"New value: +"Language of the answer: the guide or the definition, the text summary and the page links. Field names stay English. uk is accepted as ua." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "description": "Without term: every term.", + "properties": { + "attribution": { + "type": "object" + }, + "count": { + "type": "integer" + }, + "language": { + "type": "string" + }, + "terms": { + "items": { + "type": "object" + }, + "type": "array" + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "language", + "count", + "terms", + "url", + "attribution" + ], + "type": "object" + }, + { + "description": "With term: the definition and the law.", + "properties": { + "abbreviation": { + "type": [ + "string", + "null" + ] + }, + "attribution": { + "type": "object" + }, + "checked_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "definition": { + "type": "string" + }, + "en_name": { + "type": "string" + }, + "in_practice": { + "items": { + "type": "string" + }, + "type": "array" + }, + "key": { + "type": "string" + }, + "language": { + "type": "string" + }, + "language_requested": { + "type": "string" + }, + "legal_refs": { + "items": { + "type": "object" + }, + "type": "array" + }, + "name": { + "type": "string" + }, + "pt_name": { + "type": "string" + }, + "questions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "see_also": { + "items": { + "type": "object" + }, + "type": "array" + }, + "sources": { + "items": { + "type": "object" + }, + "type": "array" + }, + "updated_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "key", + "name", + "pt_name", + "en_name", + "abbreviation", + "url", + "language", + "language_requested", + "definition", + "in_practice", + "questions", + "legal_refs", + "see_also", + "updated_on", + "checked_on", + "sources", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "suggestions": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
imi_annual_cost4 fields changed- added
Input schema / properties / municipality / examplesAdded value: +[ + "Porto", + "Lisbon", + "1312" +] - changed
Input schema / properties / vpt / descriptionPrevious value: -"Valor Patrimonial Tributário — the taxable value of the property in euros. Not the purchase price"New value: +"Valor Patrimonial Tributário — the taxable value of the property in euros, from the caderneta predial. Not the purchase price" - added
Input schema / properties / vpt / examplesAdded value: +[ + "150000", + "92.540,37" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "annual_cents": { + "description": "Euro cents: yearly IMI", + "type": "integer" + }, + "attribution": { + "type": "object" + }, + "codigo": { + "description": "Four-digit Tax Authority code", + "type": "string" + }, + "distrito": { + "type": "string" + }, + "history": { + "type": "object" + }, + "municipality": { + "type": "string" + }, + "rural": { + "type": "object" + }, + "urban": { + "type": "object" + }, + "vpt_cents": { + "description": "Euro cents: the VPT given", + "type": "integer" + }, + "year": { + "type": "integer" + } + }, + "required": [ + "codigo", + "municipality", + "distrito", + "urban", + "rural", + "year", + "history", + "attribution", + "vpt_cents", + "annual_cents" + ], + "type": "object" + }, + { + "description": "Refusal rate_by_freguesia: the municipality's rate row, no yearly sum.", + "properties": { + "attribution": { + "type": "object" + }, + "codigo": { + "description": "Four-digit Tax Authority code", + "type": "string" + }, + "distrito": { + "type": "string" + }, + "error": { + "type": "string" + }, + "history": { + "type": "object" + }, + "municipality": { + "type": "string" + }, + "rural": { + "type": "object" + }, + "urban": { + "type": "object" + }, + "year": { + "type": "integer" + } + }, + "required": [ + "codigo", + "municipality", + "distrito", + "urban", + "rural", + "year", + "history", + "attribution", + "error" + ], + "type": "object" + }, + { + "description": "Refusal (isError: true). `error` is a machine code (not_found, bad_*, tool_failed…), `message` says what to fix.", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
imi_rate2 fields changed- added
Input schema / properties / municipality / examplesAdded value: +[ + "Porto", + "Lisbon", + "1312" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "attribution": { + "type": "object" + }, + "codigo": { + "description": "Four-digit Tax Authority code", + "type": "string" + }, + "distrito": { + "type": "string" + }, + "history": { + "type": "object" + }, + "municipality": { + "type": "string" + }, + "rural": { + "type": "object" + }, + "urban": { + "type": "object" + }, + "year": { + "type": "integer" + } + }, + "required": [ + "codigo", + "municipality", + "distrito", + "urban", + "rural", + "year", + "history", + "attribution" + ], + "type": "object" + }, + { + "description": "Refusal (isError: true). `error` is a machine code (not_found, bad_*, tool_failed…), `message` says what to fix.", + "properties": { + "error": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
imt_calculate14 fields changed- added
Input schema / properties / buyer_is_young / defaultAdded value: +false - changed
Input schema / properties / buyer_is_young / descriptionPrevious value: -"The buyer is 35 or under on the date of the deed, is buying their first own permanent home, is not an IRS dependant and has owned no residential property in the previous three years. Applies the reduced IMT table and the stamp duty deduction (art. 7.º-A Código do Imposto do Selo; not applied above the second band of the young buyers' table). Only applies when primary_home is true. Default: false"New value: +"The buyer is 35 or under on the date of the deed, is buying their first own permanent home, is not an IRS dependant and has owned no residential property in the previous three years. Applies the reduced IMT table and the stamp duty deduction (art. 7.º-A Código do Imposto do Selo; not applied above the second band of the young buyers' table). Only applies when primary_home is true; with primary_home false it is ignored" - added
Input schema / properties / non_resident / defaultAdded value: +false - changed
Input schema / properties / non_resident / descriptionPrevious value: -"The buyer is not and has never been tax resident in Portugal. IMT is then a flat rate with no exemption or reduction — no zero band, no young buyers' table, no stamp duty deduction (CIMT art. 17.º n.º 10); the result says what the Tax Authority annuls on request if the buyer becomes tax resident or lets the home at a moderate rent. A buyer who has already been treated as tax resident pays by the tables: leave it false. Default: false"New value: +"The buyer is not and has never been tax resident in Portugal. IMT is then a flat rate with no exemption or reduction — no zero band, no young buyers' table, no stamp duty deduction (CIMT art. 17.º n.º 10); the result says what the Tax Authority annuls on request if the buyer becomes tax resident or lets the home at a moderate rent. A buyer who has already been treated as tax resident pays by the tables: leave it false" - added
Input schema / properties / primary_home / defaultAdded value: +true - changed
Input schema / properties / primary_home / descriptionPrevious value: -"The buyer's own permanent home (habitação própria e permanente). Default: true"New value: +"The buyer's own permanent home (habitação própria e permanente); false for a second home or an investment, which has no zero band" - added
Input schema / properties / tax_haven_company / defaultAdded value: +false - changed
Input schema / properties / tax_haven_company / descriptionPrevious value: -"The buyer is a company or other entity with its tax domicile in a country, territory or region on the Portuguese list of more favourable tax regimes, or controlled directly or indirectly by such an entity. IMT is then 10 % with no exemption or reduction (CIMT art. 17.º n.º 4), whether or not it is resident, and it overrides non_resident. Never true for an individual (n.º 7). Default: false"New value: +"The buyer is a company or other entity with its tax domicile in a country, territory or region on the Portuguese list of more favourable tax regimes, or controlled directly or indirectly by such an entity. IMT is then 10 % with no exemption or reduction (CIMT art. 17.º n.º 4), whether or not it is resident, and it overrides non_resident. Never true for an individual (n.º 7)" - added
Input schema / properties / territory / defaultAdded value: +"continente" - changed
Input schema / properties / territory / descriptionPrevious value: -"Mainland Portugal (continente) or the Azores and Madeira (regioes_autonomas). Default: continente"New value: +"Mainland Portugal (continente) or the Azores and Madeira (regioes_autonomas), which have their own IMT tables" - changed
Input schema / properties / value / descriptionPrevious value: -"Purchase price as written in the contract, in euros, e.g. 250000 or 250000.50"New value: +"Purchase price as written in the contract, in euros; a dot or a space may group thousands (250.000)" - added
Input schema / properties / value / examplesAdded value: +[ + "250000", + "250000.50", + "250.000" +] - added
Input schema / properties / vpt / examplesAdded value: +[ + "180000" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "annullable": { + "type": [ + "object", + "null" + ] + }, + "attribution": { + "type": "object" + }, + "deed_source": { + "type": "object" + }, + "formatted": { + "type": "object" + }, + "imt_cents": { + "description": "Euro cents (integer)", + "type": "integer" + }, + "imt_regime": { + "description": "Which IMT rule was applied", + "type": "string" + }, + "input": { + "type": "object" + }, + "notary_estimate_cents": { + "description": "Euro cents: Casa Pronta registration price", + "type": "integer" + }, + "notes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "stamp_duty_cents": { + "description": "Euro cents, after relief", + "type": "integer" + }, + "stamp_duty_relief_cents": { + "description": "Euro cents (integer)", + "type": "integer" + }, + "taxable_base": { + "type": "string" + }, + "taxable_value_cents": { + "description": "Euro cents: the higher of price and VPT", + "type": "integer" + }, + "total_cents": { + "description": "Euro cents on top of the price", + "type": "integer" + } + }, + "required": [ + "input", + "imt_regime", + "annullable", + "taxable_value_cents", + "taxable_base", + "imt_cents", + "stamp_duty_cents", + "stamp_duty_relief_cents", + "notary_estimate_cents", + "total_cents", + "formatted", + "notes", + "attribution", + "deed_source" + ], + "type": "object" + }, + { + "properties": { + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
municipality_stats2 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en"New value: +"Language of the page links and labels; the text summary and field names stay English. uk is accepted as ua." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "attribution": { + "type": "object" + }, + "construction_barometer": { + "type": [ + "object", + "null" + ] + }, + "imi": { + "type": "object" + }, + "language": { + "type": "string" + }, + "licensed_buildings_all_works": { + "type": [ + "object", + "null" + ] + }, + "licensed_new_buildings": { + "type": [ + "object", + "null" + ] + }, + "licensed_new_dwellings": { + "type": [ + "object", + "null" + ] + }, + "municipal_cases": { + "type": [ + "object", + "null" + ] + }, + "municipality": { + "type": "object" + }, + "new_builds": { + "type": "object" + }, + "population": { + "type": [ + "object", + "null" + ] + }, + "purchasing_power": { + "description": "Index, Portugal = 100", + "type": [ + "object", + "null" + ] + }, + "sale_prices": { + "type": [ + "object", + "null" + ] + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "where_to_live": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "municipality", + "url", + "imi", + "sale_prices", + "purchasing_power", + "population", + "licensed_new_dwellings", + "licensed_new_buildings", + "licensed_buildings_all_works", + "municipal_cases", + "construction_barometer", + "new_builds", + "where_to_live", + "attribution", + "language" + ], + "type": "object" + }, + { + "properties": { + "candidates": { + "items": { + "type": "object" + }, + "type": "array" + }, + "error": { + "type": "string" + }, + "message": { + "type": "string" + }, + "suggestions": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
request_consultation25 fields changed- changed
Input schema / properties / city / descriptionPrevious value: -"Municipality in Portugal, Portuguese name (Porto, Matosinhos, Lisboa). Not needed with project"New value: +"Municipality in Portugal (Lisboa or Lisbon) or a district. Not needed with project, which sets the place" - added
Input schema / properties / city / examplesAdded value: +[ + "Porto", + "Matosinhos" +] - changed
Input schema / properties / client / descriptionPrevious value: -"Optional. Your app's host or name, e.g. claude.ai or chatgpt.com: recorded as the request's source"New value: +"Optional. Your app's host or name: recorded as the request's source" - added
Input schema / properties / client / examplesAdded value: +[ + "claude.ai", + "chatgpt.com" +] - added
Input schema / properties / deal_type / defaultAdded value: +"buy" - changed
Input schema / properties / deal_type / descriptionPrevious value: -"Default: buy"New value: +"Renting is not handled" - added
Input schema / properties / email / examplesAdded value: +[ + "maria@example.com" +] - added
Input schema / properties / email / formatAdded value: +"email" - added
Input schema / properties / language / defaultAdded value: +"en" - changed
Input schema / properties / language / descriptionPrevious value: -"The person's language: pt, en, ru, ua, de, fr, nl (uk is accepted too). The consent text and the emails come in it. Default: en"New value: +"The person's language: the consent text, the emails and the page links come in it. Another value is refused, except in mode=link, which falls back to English. uk is accepted as ua." - added
Input schema / properties / language / enumAdded value: +[ + "pt", + "en", + "ru", + "ua", + "de", + "fr", + "nl", + "uk" +] - changed
Input schema / properties / message / descriptionPrevious value: -"Optional. The person's own words, up to 2000 characters"New value: +"Optional. The person's own words" - added
Input schema / properties / message / examplesAdded value: +[ + "Close to the metro, with a balcony" +] - added
Input schema / properties / message / maxLengthAdded value: +2000 - added
Input schema / properties / mode / defaultAdded value: +"link" - changed
Input schema / properties / mode / descriptionPrevious value: -"link (default): only the form link and the consent text. prepare: check the details, get a summary, the consent text and a confirmation_token; nothing is sent. submit: send the request — the same details as in prepare plus confirmation_token, consent=true and consent_text_version, only after the person has read the consent text and explicitly agreed"New value: +"link: only the form link and the consent text. prepare: check the details, get a summary, the consent text and a confirmation_token; nothing is sent. submit: send the request — the same details as in prepare plus confirmation_token, consent=true and consent_text_version, only after the person has read the consent text and explicitly agreed" - added
Input schema / properties / name / examplesAdded value: +[ + "Maria Silva" +] - added
Input schema / properties / name / maxLengthAdded value: +120 - changed
Input schema / properties / phone / descriptionPrevious value: -"Phone in international format (+351 912 345 678). Preferred over email"New value: +"Phone in international format. Preferred over email" - added
Input schema / properties / phone / examplesAdded value: +[ + "+351 912 345 678" +] - added
Input schema / properties / preferred_time / examplesAdded value: +[ + "weekday mornings" +] - added
Input schema / properties / preferred_time / maxLengthAdded value: +120 - changed
Input schema / properties / project / descriptionPrevious value: -"Optional. Slug of a development from the flatin.pt catalogue the request is about"New value: +"Optional. Slug of the development the request is about: the slug field of search_newbuilds" - changed
Input schema / properties / property_type / descriptionPrevious value: -"Default: apartment (new_build with project)"New value: +"apartment if not given, or new_build when project is given" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "description": "mode=link: the form link and the consent text; nothing is sent.", + "properties": { + "attribution": { + "type": "object" + }, + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "consent_version": { + "description": "Same as consent_text_version", + "type": "string" + }, + "form_url": { + "description": "Absolute URL", + "type": "string" + }, + "language": { + "type": "string" + }, + "mode": { + "type": "string" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "form_url", + "consent_text", + "consent_text_version", + "consent_language", + "consent_version", + "what_happens_next", + "language", + "attribution" + ], + "type": "object" + }, + { + "description": "mode=prepare: summary, consent text and token; nothing is sent.", + "properties": { + "confirmation_token": { + "type": "string" + }, + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "expires_in_seconds": { + "type": "integer" + }, + "mode": { + "type": "string" + }, + "summary": { + "type": "object" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "summary", + "consent_text", + "consent_text_version", + "consent_language", + "confirmation_token", + "expires_in_seconds", + "what_happens_next" + ], + "type": "object" + }, + { + "description": "mode=submit: the request was received and passed on.", + "properties": { + "mode": { + "type": "string" + }, + "privacy_policy": { + "description": "Absolute URL", + "type": "string" + }, + "status": { + "type": "string" + }, + "what_happens_next": { + "type": "string" + } + }, + "required": [ + "mode", + "status", + "what_happens_next", + "privacy_policy" + ], + "type": "object" + }, + { + "properties": { + "consent_language": { + "type": "string" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + }, + "problems": { + "items": { + "type": "object" + }, + "type": "array" + }, + "retry_after_seconds": { + "type": "integer" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
search_newbuilds19 fields changed- changed
Input schema / properties / delivery_by / descriptionPrevious value: -"Completed, or promised for this year or earlier (overdue promises included), e.g. 2027. Projects with no announced date are left out"New value: +"Completed, or promised for this year or earlier (overdue promises included), e.g. 2027; at most five years back. Projects with no announced date are left out" - added
Input schema / properties / delivery_by / maximumAdded value: +2100 - added
Input schema / properties / language / defaultAdded value: +"en" - changed
Input schema / properties / language / descriptionPrevious value: -"Language of the page URLs and labels: pt, en, ru, ua, de, fr, nl. Default en"New value: +"Language of the page URLs and of the labels (stage, typology, nearby places); the text summary shows the typology labels in it. Field names stay English. uk is accepted as ua." - changed
Input schema / properties / language / enumPrevious value: -[ - "pt", - "en", - "ru", - "ua", - "de", - "fr", - "nl" -]New value: +[ + "pt", + "en", + "ru", + "ua", + "de", + "fr", + "nl", + "uk" +] - added
Input schema / properties / limit / defaultAdded value: +10 - changed
Input schema / properties / limit / descriptionPrevious value: -"Results per call, default 10"New value: +"Results per call" - added
Input schema / properties / municipality / examplesAdded value: +[ + "Porto", + "Vila Nova de Gaia", + "1312" +] - added
Input schema / properties / offset / defaultAdded value: +0 - changed
Input schema / properties / offset / descriptionPrevious value: -"Skip this many results (use next_offset)"New value: +"Skip this many results: pass next_offset from the previous answer" - added
Input schema / properties / on_sale / defaultAdded value: +false - changed
Input schema / properties / on_sale / descriptionPrevious value: -"Only projects with a published price. Default false"New value: +"Only projects with a published price" - changed
Input schema / properties / parish / descriptionPrevious value: -"Parish (freguesia) name, e.g. Paranhos. Exact name, accents optional"New value: +"Parish (freguesia) name. Exact name, accents optional" - added
Input schema / properties / parish / examplesAdded value: +[ + "Paranhos" +] - added
Input schema / properties / price_max / maximumAdded value: +999999999 - added
Input schema / properties / price_min / maximumAdded value: +999999999 - added
Input schema / properties / sort / defaultAdded value: +"price" - changed
Input schema / properties / sort / descriptionPrevious value: -"price (cheapest first, default), name, delivery (soonest first), new (recently added first). Projects with a price always come before those without"New value: +"price: cheapest first; delivery: soonest first; new: recently added first. Projects with a price always come before those without" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "properties": { + "attribution": { + "type": "object" + }, + "catalog_url": { + "description": "Absolute URL", + "type": "string" + }, + "language": { + "type": "string" + }, + "limit": { + "type": "integer" + }, + "next_offset": { + "description": "Pass as offset for the next page; null = last", + "type": [ + "integer", + "null" + ] + }, + "offset": { + "type": "integer" + }, + "results": { + "items": { + "type": "object" + }, + "type": "array" + }, + "total": { + "type": "integer" + } + }, + "required": [ + "total", + "offset", + "limit", + "next_offset", + "language", + "catalog_url", + "results", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "candidates": { + "items": { + "type": "object" + }, + "type": "array" + }, + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + }, + "suggestions": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
subscribe_digest13 fields changed- changed
Input schema / properties / city / descriptionPrevious value: -"Municipality, Portuguese name (Porto, Lisboa). Required for construction; empty means all of Portugal for new_developments"New value: +"Municipality (Lisboa or Lisbon). Required for construction; empty means all of Portugal for new_developments" - added
Input schema / properties / city / examplesAdded value: +[ + "Porto", + "Vila Nova de Gaia" +] - changed
Input schema / properties / client / descriptionPrevious value: -"Optional. Your app's host or name, e.g. claude.ai or chatgpt.com: recorded as the request's source"New value: +"Optional. Your app's host or name: recorded as the request's source" - added
Input schema / properties / client / examplesAdded value: +[ + "claude.ai", + "chatgpt.com" +] - added
Input schema / properties / email / examplesAdded value: +[ + "maria@example.com" +] - added
Input schema / properties / email / formatAdded value: +"email" - added
Input schema / properties / language / defaultAdded value: +"en" - changed
Input schema / properties / language / descriptionPrevious value: -"The person's language: pt, en, ru, ua, de, fr, nl (uk is accepted too). The consent text and the emails come in it. Default: en"New value: +"The person's language: the consent text and the emails come in it. uk is accepted as ua." - added
Input schema / properties / language / enumAdded value: +[ + "pt", + "en", + "ru", + "ua", + "de", + "fr", + "nl", + "uk" +] - added
Input schema / properties / parish / examplesAdded value: +[ + "Paranhos" +] - added
Input schema / properties / what / defaultAdded value: +"new_developments" - changed
Input schema / properties / what / descriptionPrevious value: -"new_developments (default): new-build developments matching the filter, daily email when something new appears. construction: newly licensed construction in a municipality (\"what is being built\"), weekly"New value: +"new_developments: new-build developments matching the filter, daily email when something new appears. construction: newly licensed construction in a municipality (\"what is being built\"), weekly" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "description": "Always the same, whatever the address's state: a confirmation email was requested; nothing is active until the person clicks it.", + "properties": { + "confirm_within_days": { + "type": "integer" + }, + "consent_text": { + "type": "string" + }, + "consent_text_version": { + "type": "string" + }, + "frequency": { + "type": "string" + }, + "language": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "status": { + "type": "string" + }, + "what": { + "type": "string" + } + }, + "required": [ + "status", + "what", + "scope", + "frequency", + "confirm_within_days", + "consent_text", + "consent_text_version", + "language" + ], + "type": "object" + }, + { + "properties": { + "error": { + "type": "string" + }, + "field": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + }, + "problems": { + "items": { + "type": "object" + }, + "type": "array" + }, + "retry_after_seconds": { + "type": "integer" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
- Changed
where_to_live5 fields changed- added
Input schema / properties / include / defaultAdded value: +[ + "areas", + "noise", + "safety" +] - changed
Input schema / properties / include / descriptionPrevious value: -"Parts of the guide to return. Default: areas, noise, safety"New value: +"Parts of the guide to return; all returns every section" - changed
Input schema / properties / language / descriptionPrevious value: -"Language of the site content in the answer (verdicts, definitions, labels) and of the page links: pt, en, ru, ua (or uk), de, fr, nl. Field names and the summary stay English. Default: en"New value: +"Language of the answer: the guide or the definition, the text summary and the page links. Field names stay English. uk is accepted as ua." - changed
Input schema / properties / profile / descriptionPrevious value: -"Keep the areas that suit this profile; areas we advise against are always kept"New value: +"Keep the areas that suit this profile; profile never removes the areas we advise against" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "anyOf": [ + { + "description": "Without city: the guides that exist.", + "properties": { + "attribution": { + "type": "object" + }, + "guides": { + "items": { + "type": "object" + }, + "type": "array" + }, + "language": { + "type": "string" + }, + "profiles": { + "items": { + "type": "string" + }, + "type": "array" + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "language", + "guides", + "profiles", + "url", + "attribution" + ], + "type": "object" + }, + { + "description": "With city: one guide's verdict area by area.", + "properties": { + "areas": { + "items": { + "type": "object" + }, + "type": "array" + }, + "attribution": { + "type": "object" + }, + "filters": { + "type": "object" + }, + "guide": { + "type": "object" + }, + "hub_url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "language": { + "type": "string" + }, + "language_requested": { + "type": "string" + }, + "lede": { + "type": "string" + }, + "published_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "sections": { + "items": { + "type": "object" + }, + "type": "array" + }, + "sources": { + "items": { + "type": "object" + }, + "type": "array" + }, + "title": { + "type": "string" + }, + "updated_on": { + "description": "Date, YYYY-MM-DD", + "type": "string" + }, + "url": { + "description": "Absolute URL or null", + "type": [ + "string", + "null" + ] + }, + "verdict_scale": { + "type": "object" + } + }, + "required": [ + "guide", + "language", + "language_requested", + "title", + "lede", + "filters", + "verdict_scale", + "areas", + "sections", + "url", + "hub_url", + "published_on", + "updated_on", + "sources", + "attribution" + ], + "type": "object" + }, + { + "properties": { + "error": { + "type": "string" + }, + "guides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "message": { + "type": "string" + } + }, + "required": [ + "error", + "message" + ], + "type": "object" + } + ], + "description": "Success, or a refusal with an error code. Units: *_cents euro cents, *_eur euros, *_eur_m2 euros per m², *_pct and percent in percent.", + "type": "object" +}
1 tool update
- Changed
imt_calculate2 fields changed- added
Input schema / properties / non_residentAdded value: +{ + "description": "The buyer is not and has never been tax resident in Portugal. IMT is then a flat rate with no exemption or reduction — no zero band, no young buyers' table, no stamp duty deduction (CIMT art. 17.º n.º 10); the result says what the Tax Authority annuls on request if the buyer becomes tax resident or lets the home at a moderate rent. A buyer who has already been treated as tax resident pays by the tables: leave it false. Default: false", + "type": "boolean" +} - added
Input schema / properties / tax_haven_companyAdded value: +{ + "description": "The buyer is a company or other entity with its tax domicile in a country, territory or region on the Portuguese list of more favourable tax regimes, or controlled directly or indirectly by such an entity. IMT is then 10 % with no exemption or reduction (CIMT art. 17.º n.º 4), whether or not it is resident, and it overrides non_resident. Never true for an individual (n.º 7). Default: false", + "type": "boolean" +}
11 tool updates
- Added
compare_municipalities - Added
construction_barometer - Added
get_newbuild - Added
glossary_lookup - Changed
imi_annual_cost1 field changed- changed
Input schema / properties / municipality / descriptionPrevious value: -"Municipality name in Portuguese (Porto, Lisboa, Vila Nova de Gaia) or its four-digit code (1312)"New value: +"Municipality name (Porto, Lisboa or Lisbon, Vila Nova de Gaia) or its four-digit code (1312)"
- Changed
imi_rate1 field changed- changed
Input schema / properties / municipality / descriptionPrevious value: -"Municipality name in Portuguese (Porto, Lisboa, Vila Nova de Gaia) or its four-digit code (1312)"New value: +"Municipality name (Porto, Lisboa or Lisbon, Vila Nova de Gaia) or its four-digit code (1312)"
- Added
municipality_stats - Changed
request_consultation19 fields changed- added
Input schema / properties / budgetAdded value: +{ + "description": "Optional. Budget in whole euros, e.g. 350000", + "type": "integer" +} - added
Input schema / properties / channelAdded value: +{ + "description": "How the person wants to be contacted on that phone", + "enum": [ + "whatsapp", + "telegram", + "call" + ], + "type": "string" +} - added
Input schema / properties / cityAdded value: +{ + "description": "Municipality in Portugal, Portuguese name (Porto, Matosinhos, Lisboa). Not needed with project", + "type": "string" +} - added
Input schema / properties / clientAdded value: +{ + "description": "Optional. Your app's host or name, e.g. claude.ai or chatgpt.com: recorded as the request's source", + "type": "string" +} - added
Input schema / properties / confirmation_tokenAdded value: +{ + "description": "submit only: the token returned by prepare", + "type": "string" +} - added
Input schema / properties / consentAdded value: +{ + "description": "submit only: true once the person has read the consent text returned by prepare and explicitly agreed", + "type": "boolean" +} - added
Input schema / properties / consent_text_versionAdded value: +{ + "description": "submit only: consent_text_version returned by prepare", + "type": "string" +} - added
Input schema / properties / deal_typeAdded value: +{ + "description": "Default: buy", + "enum": [ + "buy", + "sell" + ], + "type": "string" +} - added
Input schema / properties / emailAdded value: +{ + "description": "Only if the person gives no phone", + "type": "string" +} - added
Input schema / properties / intentAdded value: +{ + "description": "Optional. visit and reserve only with a project on sale, notify only with a project not yet on sale", + "enum": [ + "info", + "callback", + "visit", + "reserve", + "notify" + ], + "type": "string" +} - changed
Input schema / properties / language / descriptionPrevious value: -"The user's language: pt, en, ru, ua, de, fr, nl (uk is accepted too). Default: en"New value: +"The person's language: pt, en, ru, ua, de, fr, nl (uk is accepted too). The consent text and the emails come in it. Default: en" - added
Input schema / properties / messageAdded value: +{ + "description": "Optional. The person's own words, up to 2000 characters", + "type": "string" +} - added
Input schema / properties / modeAdded value: +{ + "description": "link (default): only the form link and the consent text. prepare: check the details, get a summary, the consent text and a confirmation_token; nothing is sent. submit: send the request — the same details as in prepare plus confirmation_token, consent=true and consent_text_version, only after the person has read the consent text and explicitly agreed", + "enum": [ + "link", + "prepare", + "submit" + ], + "type": "string" +} - added
Input schema / properties / nameAdded value: +{ + "description": "The person's name", + "type": "string" +} - added
Input schema / properties / phoneAdded value: +{ + "description": "Phone in international format (+351 912 345 678). Preferred over email", + "type": "string" +} - added
Input schema / properties / preferred_timeAdded value: +{ + "description": "Optional, with intent=visit: when suits the person", + "type": "string" +} - added
Input schema / properties / projectAdded value: +{ + "description": "Optional. Slug of a development from the flatin.pt catalogue the request is about", + "type": "string" +} - added
Input schema / properties / property_typeAdded value: +{ + "description": "Default: apartment (new_build with project)", + "enum": [ + "apartment", + "house", + "commercial", + "new_build" + ], + "type": "string" +} - added
Input schema / properties / typologyAdded value: +{ + "description": "Optional. Bedroom counts wanted (T2 = two bedrooms)", + "items": { + "enum": [ + "T0", + "T1", + "T2", + "T3", + "T4+" + ], + "type": "string" + }, + "type": "array" +}
- Added
search_newbuilds - Added
subscribe_digest - Added
where_to_live
1 tool update
- Changed
imt_calculate2 fields changed- changed
Input schema / properties / value / descriptionPrevious value: -"Property price in euros, e.g. 250000 or 250000.50"New value: +"Purchase price as written in the contract, in euros, e.g. 250000 or 250000.50" - added
Input schema / properties / vptAdded value: +{ + "description": "Optional. The VPT (valor patrimonial tributário) from the caderneta predial, in euros. IMT and stamp duty are charged on the higher of the price and the VPT (CIMT art. 12.º n.º 1), so pass it when it is known", + "type": "string" +}
3 tool updates
- Changed
imi_annual_cost1 field changed- changed
Input schema / properties / municipality / descriptionPrevious value: -"Municipality name (Porto, Vila Nova de Gaia) or its four-digit code (1312)"New value: +"Municipality name in Portuguese (Porto, Lisboa, Vila Nova de Gaia) or its four-digit code (1312)"
- Changed
imi_rate1 field changed- changed
Input schema / properties / municipality / descriptionPrevious value: -"Municipality name (Porto, Vila Nova de Gaia) or its four-digit code (1312)"New value: +"Municipality name in Portuguese (Porto, Lisboa, Vila Nova de Gaia) or its four-digit code (1312)"
- Changed
imt_calculate1 field changed- changed
Input schema / properties / buyer_is_young / descriptionPrevious value: -"The buyer is 35 or under and this is their first home. Only applies when primary_home is true. Default: false"New value: +"The buyer is 35 or under on the date of the deed, is buying their first own permanent home, is not an IRS dependant and has owned no residential property in the previous three years. Applies the reduced IMT table and the stamp duty deduction (art. 7.º-A Código do Imposto do Selo; not applied above the second band of the young buyers' table). Only applies when primary_home is true. Default: false"
4 tool updates
- First observed
imi_annual_cost - First observed
imi_rate - First observed
imt_calculate - First observed
request_consultation
Publisher details
- Operator
- HOLY CHAOS, UNIPESSOAL LDA
- Operator website
- https://flatin.pt
- Vendor relationship
- Unknown
- Documentation
- https://flatin.pt/en/tools/api-and-data/
- Trust center
- Unknown
- Restrictions
- No API key, no account, no paid plan, no regional limits. Public rate limit: 120 requests per minute per IP address.
Related MCP Connectors
Free MCP server with Bulgarian property prices, rental yields, deal costs and neighbourhood profiles
Unofficial MCP server for the public PortlandMaps property/permit/zoning API. Not city-affiliated.
Portugal PDM zoning with official sources. One free query per account; no purchases.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables users to calculate Portuguese property purchase costs (IMT, stamp duty, deed/registration) and query annual IMI rates and costs for all 308 municipalities, with sourced figures.MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for accessing BPstat (Banco de Portugal) statistics API without API keys. Enables querying Portuguese central bank data through natural language.13 npmMIT
- AlicenseNot gradedqualityCmaintenanceUK property data MCP server for AI hosts (Claude, ChatGPT). Wraps Land Registry, Rightmove, EPC, rental yields, stamp duty, and Companies House into 13 tools.2MIT
- AlicenseAqualityAmaintenanceUK property data MCP server — Land Registry comps, EPC, Rightmove, rental yields, stamp duty, Companies House. 13 tools.1318MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.