Skip to main content
Glama

Underwrite an Austrian buy-to-let purchase

underwrite_property
Read-onlyIdempotent

Analyse an Austrian residential property as a rental investment: acquisition costs, annuity loan payment, monthly cash flow before and after income tax, gross and net yield, cash-on-cash return, debt cover (DSCR), break-even rent, whether statutory rent caps (MRG) apply and the Richtwert cap, depreciation (AfA) with the legal land share, a 25-year Liebhaberei check, and risk flags. Use when evaluating whether a specific flat or house is a good buy-to-let deal. Inputs in EUR; rents and owner costs are monthly and net of VAT. Pass what you know: missing facts fall back to documented assumptions and are flagged. The JSON is compact by default (key figures, flags, citations); pass detail "full" for every line, the tax years and the rules used. Not covered: rent increases or interest-rate changes over time, tax credits, Richtwert surcharges and deductions (Zuschläge/Abschläge).

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "purchasePrice": "<purchasePrice>",
      "broker": "<broker>",
      "rent": "<rent>"
    },
    "name": "underwrite_property"
  }
}

Input Schema

NameRequiredDescriptionDefault
taxNoFacts for the income tax on rent and the depreciation (AfA). Omit to use flagged defaults (40% marginal rate, 40% land share).
rentYesExpected rent.
brokerYesBroker commission, or "none" if the purchase is commission-free (provisionsfrei).
detailNoHow much of the result to return as JSON. "summary" (default) keeps the key figures, flags, assumptions, limitations and deduplicated citations (about 40% of the size for underwrite_property, 60% for estimate_acquisition_costs). "full" adds every line item with its calculation and citations, the tax years and the rules used. The readable text is the same in both.
propertyNoProperty facts. Pass what you know; missing facts are flagged.
financingNoMortgage financing. Omit for a cash purchase.
ownerCostsNoCosts the owner pays that cannot be passed on to the tenant.
assumptionsNoOverride default assumptions. Omit to use documented defaults.
purchasePriceYesPurchase price in EUR (the agreed price for the property), e.g. 249000.
valuationDateNoDate whose rules apply, YYYY-MM-DD, usually today or the expected signing date. Defaults to today (Vienna time). Covered: 2025-04-01 to 2027-12-31.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / properties / detail
      Added value: +{
      +  "description": "How much of the result to return as JSON. \"summary\" (default) keeps the key figures, flags, assumptions, limitations and deduplicated citations (about 40% of the size for underwrite_property, 60% for estimate_acquisition_costs). \"full\" adds every line item with its calculation and citations, the tax years and the rules used. The readable text is the same in both.",
      +  "enum": [
      +    "summary",
      +    "full"
      +  ],
      +  "type": "string"
      +}
  2. Changed2 schema fields changed
    • addedInput schema / properties / property / properties / state
      Added value: +{
      +  "description": "Bundesland (ä → ae, ö → oe), e.g. \"wien\" for Vienna, \"steiermark\" for Graz. Needed for the Richtwert rent cap.",
      +  "enum": [
      +    "burgenland",
      +    "kaernten",
      +    "niederoesterreich",
      +    "oberoesterreich",
      +    "salzburg",
      +    "steiermark",
      +    "tirol",
      +    "vorarlberg",
      +    "wien"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / rent / properties / fixedTerm
      Added value: +{
      +  "description": "Whether the lease is fixed-term (befristet). For rent-capped flats this lowers the cap by 25%. Omit if unknown.",
      +  "type": "boolean"
      +}
  3. Changed2 schema fields changed
    • addedInput schema / properties / assumptions / properties / marginalTaxRatePct
      Added value: +{
      +  "description": "Owner's marginal income tax rate in %, applied to the rental result. Default 40. Ignored when tax.otherTaxableIncome is given.",
      +  "type": "number"
      +}
    • addedInput schema / properties / tax
      Added value: +{
      +  "description": "Facts for the income tax on rent and the depreciation (AfA). Omit to use flagged defaults (40% marginal rate, 40% land share).",
      +  "properties": {
      +    "averageLandPricePerM2": {
      +      "description": "Average price of building land in the municipality, EUR per m². Under 400 in a town under 100,000 inhabitants → 20% land share.",
      +      "type": "number"
      +    },
      +    "landSharePct": {
      +      "description": "Land share of the purchase in %, if proven (e.g. expert opinion). Otherwise presumed at 20, 30 or 40% by law.",
      +      "type": "number"
      +    },
      +    "municipalityInhabitants": {
      +      "description": "Inhabitants of the municipality (e.g. Vienna ≈ 2,000,000). Decides the presumed land share together with the land price.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "otherTaxableIncome": {
      +      "description": "Owner's other taxable income per year in EUR (e.g. gross salary minus social security). Enables the exact income tax tariff.",
      +      "type": "number"
      +    }
      +  },
      +  "type": "object"
      +}
  4. First observed

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/closed-world, yet the description adds real behavioral context: missing facts fall back to documented assumptions and are flagged, inputs are EUR with monthly net-of-VAT rents, and the JSON is compact by default unless detail='full'.

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?

Front-loaded with the core purpose, then the metric list, then usage, units, and limitations. The long output enumeration is dense but each element is load-bearing for an underwriting tool, and nothing is redundant.

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 10-parameter nested tool with no output schema, the description covers what is computed, the two output verbosity modes, default/fallback handling, units, and explicit scope limits — enough for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema documents every parameter, but the description still adds unit/semantic meaning ('Inputs in EUR; rents and owner costs are monthly and net of VAT') and the fallback behavior for omitted facts, going beyond the schema baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Analyse/underwrite') and resource (an Austrian residential buy-to-let) and enumerates the exact outputs computed (yields, DSCR, break-even rent, MRG caps, AfA, Liebhaberei check). The sibling estimate_acquisition_costs is only name-dropped inside the detail parameter, so the differentiation from siblings is implicit rather than explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Use when evaluating whether a specific flat or house is a good buy-to-let deal' gives clear context, and the 'Not covered' clause (rent increases, interest-rate changes, tax credits, Richtwert surcharges/deductions) scopes it. However, it never says when to prefer the sibling estimate_acquisition_costs or get_rules instead.

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.