Skip to main content
Glama
apetta
by apetta

perpetuity

Calculate present value of infinite payment streams for financial analysis of preferred stocks, endowments, and perpetual assets using level, growing, or due formulas.

Instructions

Calculate present value of a perpetuity (infinite series of payments).

A perpetuity is an annuity that continues forever. Common in: - Preferred stock dividends - Endowment funds - Real estate with infinite rental income - UK Consol bonds (historically)

Formulas: Level Ordinary: PV = C / r Level Due: PV = C / r × (1 + r) Growing: PV = C / (r - g), where r > g

Examples:

LEVEL PERPETUITY: £1000 annual payment at 5% payment=1000, rate=0.05 Result: PV = £20,000

GROWING PERPETUITY: £1000 payment growing 3% annually at 8% discount payment=1000, rate=0.08, growth_rate=0.03 Result: PV = £20,000

PERPETUITY DUE: £1000 at period start at 5% payment=1000, rate=0.05, when='begin' Result: PV = £21,000

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
contextNoOptional annotation to label this calculation (e.g., 'Bond A PV', 'Q2 revenue'). Appears in results for easy identification.
output_modeNoOutput format: full (default), compact, minimal, value, or final. See batch_execute tool for details.full
paymentYesPeriodic payment amount (e.g., 1000)
rateYesDiscount rate per period (e.g., 0.05)
growth_rateNoPayment growth rate (None or 0 for level, e.g., 0.03 for growing)
whenNoPayment timing: 'end' or 'begin'end

Implementation Reference

  • MCP tool registration decorator defining the perpetuity tool's name, description, examples, and metadata annotations.
    @mcp.tool( name="perpetuity", description="""Calculate present value of a perpetuity (infinite series of payments). A perpetuity is an annuity that continues forever. Common in: - Preferred stock dividends - Endowment funds - Real estate with infinite rental income - UK Consol bonds (historically) Formulas: Level Ordinary: PV = C / r Level Due: PV = C / r × (1 + r) Growing: PV = C / (r - g), where r > g Examples: LEVEL PERPETUITY: £1000 annual payment at 5% payment=1000, rate=0.05 Result: PV = £20,000 GROWING PERPETUITY: £1000 payment growing 3% annually at 8% discount payment=1000, rate=0.08, growth_rate=0.03 Result: PV = £20,000 PERPETUITY DUE: £1000 at period start at 5% payment=1000, rate=0.05, when='begin' Result: PV = £21,000""", annotations=ToolAnnotations( title="Perpetuity Calculations", readOnlyHint=True, idempotentHint=True, ), )
  • Handler function implementing present value calculation for level perpetuity (PV=C/r), growing perpetuity (PV=C/(r-g)), and perpetuity due (PV=C/r * (1+r)), with input validation and metadata generation.
    async def perpetuity( payment: Annotated[float, Field(description="Periodic payment amount (e.g., 1000)")], rate: Annotated[float, Field(description="Discount rate per period (e.g., 0.05)", gt=0)], growth_rate: Annotated[ float | None, Field( description="Payment growth rate (None or 0 for level, e.g., 0.03 for growing)", ge=0 ), ] = None, when: Annotated[ Literal["end", "begin"], Field(description="Payment timing: 'end' or 'begin'") ] = "end", ) -> str: """Calculate present value of perpetuity.""" try: # Validate inputs if rate <= 0: raise ValueError("Discount rate must be positive") if growth_rate is not None: if growth_rate < 0: raise ValueError("Growth rate cannot be negative") if growth_rate >= rate: raise ValueError( f"Growth rate ({growth_rate}) must be less than discount rate ({rate}) " "for perpetuity to have finite value" ) # Calculate present value based on type if growth_rate is not None and growth_rate > 0: # Growing perpetuity: PV = C / (r - g) pv = payment / (rate - growth_rate) perpetuity_type = "growing" elif when == "begin": # Perpetuity due (payments at beginning): PV = C/r × (1+r) pv = (payment / rate) * (1 + rate) perpetuity_type = "level_due" else: # Ordinary perpetuity (payments at end): PV = C / r pv = payment / rate perpetuity_type = "level_ordinary" # Build metadata metadata: Dict[str, Any] = { "type": perpetuity_type, "payment": payment, "rate": rate, } if growth_rate is not None: metadata["growth_rate"] = growth_rate if when != "end": metadata["when"] = when return format_result(float(pv), metadata) except Exception as e: raise ValueError(f"Perpetuity calculation failed: {str(e)}")
  • TOOL_CATEGORIES dictionary listing 'perpetuity' under Financial category for batch execution tool registry.
    "Financial": ["financial_calcs", "compound_interest", "perpetuity"],

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/apetta/vibe-math-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server