Skip to main content
Glama

Property DCF from a rent roll

calc_dcf_pro_forma
Read-onlyIdempotent

Property-level discounted cash flow from an in-place rent roll: each lease's rent, escalations, remaining term, and expense recovery (NNN, gross, base year), then at expiration one blended lease weighted by the renewal probability (renewal vs new-tenant rent, free rent, TI, leasing commissions, and new-tenant downtime, with fractional downtime and free rent kept as part months rather than rounded); market rent growth, general vacancy and credit loss, operating expenses, management fee, and capital reserves. Returns the annual cash-flow table (NOI and cash flow before debt) for the hold plus one year, the exit value at a cap rate on forward (or trailing) NOI less selling costs, the value (PV at the discount rate, end-of-year or mid-year), and with a purchase price the NPV, unlevered IRR, and equity multiple, with every lease event and convention stated. Deterministic: use this instead of doing the math yourself; cite formula calc.dcf_pro_forma@2 and the returned steps, and surface any warnings.

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": {
      "hold_years": "<hold_years>",
      "leases": "<leases>",
      "market_leasing": "<market_leasing>",
      "exit_cap_rate": "<exit_cap_rate>",
      "discount_rate": "<discount_rate>"
    },
    "name": "calc_dcf_pro_forma"
  }
}

Input Schema

NameRequiredDescriptionDefault
leasesYesRent roll: one entry per lease or vacant suite (at most 200). The building area is the sum of their areas.
timingNo"end_of_year": each year's cash flow is discounted (1 + r)^y (Excel NPV). "mid_year": operating cash flows at (1 + r)^(y − 0.5); the sale is always discounted at the end of the hold.end_of_year
hold_yearsYesHolding period in years. The property is sold at the end of the last year; one more year is projected for the forward NOI.
discount_rateYesAnnual unlevered discount rate, e.g. 0.08. The present value at this rate is the value.
exit_cap_rateYesExit (terminal) cap rate applied to the exit NOI, e.g. 0.07.
exit_noi_basisNo"forward": the NOI of the year after the hold (the usual convention); "trailing": the NOI of the final hold year.forward
market_leasingYesMarket leasing assumptions applied at every lease expiration (and to space vacant at the start). A lease's own `leasing` object overrides any of them.
purchase_priceNoPrice paid at the start, USD. Adds the NPV (value − price), the unlevered IRR and the going-in cap rate on price.
credit_loss_rateNoCredit loss as a share of gross revenue, on top of general vacancy.
selling_cost_rateNoSelling costs as a share of the gross sale price, e.g. 0.02.
expense_growth_rateNoAnnual growth of operating expenses and capital reserves, e.g. 0.03: year y = year 1 × (1 + g)^(y − 1).
management_fee_rateNoManagement fee as a share of effective gross revenue, e.g. 0.03; not recovered.
general_vacancy_rateNoGeneral vacancy allowance as a share of gross revenue (base rent after free rent, plus recoveries), on top of the downtime modelled at rollover.
market_rent_growth_rateNoAnnual market rent growth, e.g. 0.03. Market rent and TI in analysis year y = today's × (1 + g)^(y − 1).
capital_reserve_psf_annualNoYear-1 capital reserve, USD/SF/yr over the building area, below NOI. Grows with expense_growth_rate.
operating_expenses_psf_annualNoYear-1 recoverable operating expenses, USD/SF/yr over the whole building area.
non_recoverable_expenses_annualNoYear-1 operating expenses no tenant reimburses, USD/yr.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / properties / leases / items / properties / leasing / properties / downtime_months / description
      Previous value: -"Months vacant before a new tenant starts paying (no downtime is assumed on renewal). Blended downtime = (1 − renewal_probability) × this, rounded to whole months."New value: +"Months vacant before a new tenant starts paying (no downtime is assumed on renewal). Blended downtime = (1 − renewal_probability) × this, kept fractional, not rounded: the suite is vacant for the whole months and the rollover lease's first month collects 1 − the fraction of its rent and recoveries (0.45 months of downtime: the first month collects 55%)."
    • changedInput schema / properties / leases / items / properties / leasing / properties / free_rent_months_renewal / description
      Previous value: -"Months of free base rent on a renewal."New value: +"Months of free base rent on a renewal. Blended free rent = p × this + (1 − p) × free_rent_months_new, kept fractional: the whole months are fully abated and the next month by the fraction."
    • changedInput schema / properties / market_leasing / properties / downtime_months / description
      Previous value: -"Months vacant before a new tenant starts paying (no downtime is assumed on renewal). Blended downtime = (1 − renewal_probability) × this, rounded to whole months."New value: +"Months vacant before a new tenant starts paying (no downtime is assumed on renewal). Blended downtime = (1 − renewal_probability) × this, kept fractional, not rounded: the suite is vacant for the whole months and the rollover lease's first month collects 1 − the fraction of its rent and recoveries (0.45 months of downtime: the first month collects 55%)."
    • changedInput schema / properties / market_leasing / properties / free_rent_months_renewal / description
      Previous value: -"Months of free base rent on a renewal."New value: +"Months of free base rent on a renewal. Blended free rent = p × this + (1 − p) × free_rent_months_new, kept fractional: the whole months are fully abated and the next month by the fraction."
  2. Added

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnly=true, destructive=false, idempotent=true and closed-world, so the safety profile is fully covered. The description adds genuinely useful behavior beyond that: determinism, the exact return set, the 'every lease event and convention stated' guarantee, and the fractional-month convention for downtime and free rent. It still says nothing about limits (200-lease cap), failure modes, or what a warning looks like, so it is solid but not exceptional.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose, then the input enumeration, then outputs, then the determinism/citation directive — a sensible information hierarchy. The first sentence is a long run-on colon-chain that takes effort to parse, which costs it the top mark, but no clause is filler.

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?

There is no output schema and 17 parameters with nested per-lease overrides, so the description must explain the return surface — and it does, naming the cash-flow table, forward/trailing exit value net of selling costs, PV under either timing convention, and the NPV/IRR/equity-multiple add-ons when purchase_price is supplied. Combined with annotations and a fully described schema, an agent has everything needed to call it and interpret the result.

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

Parameters3/5

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

With schema description coverage at 100% and deeply documented nested fields, the schema already carries nearly all parameter meaning, so the baseline is 3. The description does add conceptual linkage the schema cannot: the rollover is blended 'weighted by the renewal probability' across renewal vs. new-tenant rent, free rent, TI, commissions and downtime, and that market rent growth, vacancy, credit loss and reserves all feed the same build.

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?

Opens with a specific verb+resource: 'Property-level discounted cash flow from an in-place rent roll', then enumerates exactly what the model consumes (rent, escalations, term, recovery structure) and produces (NOI/cash-flow table, exit value, PV, NPV/IRR/equity multiple). It is unmistakably a full DCF rather than a single-year cap or an IRR-only tool, but no sibling (calc_direct_cap, calc_irr, calc_multifamily_rent_roll) is named to make the boundary 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?

Gives a clear directive with an alternative: 'Deterministic: use this instead of doing the math yourself', plus operational instructions to cite formula calc.dcf_pro_forma@2 and surface warnings. It does not tell the agent when a simpler sibling (direct cap, standalone IRR) would be the better call, which keeps it short of a 5.

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.