Skip to main content
Glama

flatin.pt — Portuguese homes: taxes, construction, new-builds

Calculate the yearly IMI from the taxable value

imi_annual_cost
Read-onlyIdempotent

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).

Input Schema

NameRequiredDescriptionDefault
vptYesValor Patrimonial Tributário — the taxable value of the property in euros, from the caderneta predial. Not the purchase price
municipalityYesMunicipality name (Porto, Lisboa or Lisbon, Vila Nova de Gaia) or its four-digit code (1312)

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • addedInput schema / properties / municipality / examples
      Added value: +[
      +  "Porto",
      +  "Lisbon",
      +  "1312"
      +]
    • changedInput schema / properties / vpt / description
      Previous 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"
    • addedInput schema / properties / vpt / examples
      Added value: +[
      +  "150000",
      +  "92.540,37"
      +]
    • changedOutput 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"
      +}
  2. Changed1 schema field changed
    • changedInput schema / properties / municipality / description
      Previous 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)"
  3. Changed1 schema field changed
    • changedInput schema / properties / municipality / description
      Previous 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)"
  4. First observed

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources