Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Changed the definition of "calculate_opportunity_cost" and "compare_payoff_vs_invest"
{"properties":{"annual_gross_income":{"default":null,"description":"Annual gross income in dollars, used as adjusted gross income for the tax on investment gains at the horizon. Optional; with filing_status it enables the after-tax opportunity cost. Held at this amount in the year of the assumed investment sale. Must be zero or more and no more than $1,000,000,000.","maximum":1000000000,"minimum":0,"type":["number","null"]},"annual_return_pct":{"description":"Effective annual investment return ⟨44 unchanged words⟩ "type":["string","null"]},"filing_status":{"default":null,"description":"Tax filing status: 'single', 'married', or 'head_of_household'. Optional; matched case-insensitively. Required, with annual_gross_income, for the after-tax opportunity cost.","enum":["single","married","head_of_household",null],"type":["string","null"]},"label":{"default":null,"description":"What ⟨47 unchanged words⟩ "tax_bracket_pct":{"default":null,"description":"TaxNotbracketused.asKeptasopercentage,olderappliedcallsasstillawork;flatanhaircutafter-taxtofiguretheneedsinvestmentfiling_statusgain.and annual_gross_income. Decimal from 0 to 100. Optional.","type":["number","null"]},"tax_year":{"default":null,"description":"Tax year, 2025 or 2026. Year 1 of the horizon, so the assumed sale of the investments falls in tax year tax_year + years - 1. Optional; defaults to 2026 when omitted.","maximum":2026,"minimum":2025,"type":["integer","null"]},"years":{"description" ⟨19 unchanged words⟩
⟨21 unchanged words⟩ a time horizon. Accounts for post-payoff investing,taxoptionallyimplicationstaxes the investment gain once at the horizon (this needs filing_status and annual_gross_income), and finds the break-even investment return rate. ⟨111 unchanged words⟩
{"properties":{"annual_gross_income":{"default":null,"description":"Annual gross income in dollars, used as adjusted gross income for the tax on investment gains at the horizon. Optional; with filing_status it enables the after-tax comparison. Held at this amount in the year of the assumed investment sale. Must be zero or more and no more than $1,000,000,000.","maximum":1000000000,"minimum":0,"type":["number","null"]},"chart_title":{"default":null,"description":"Override ⟨94 unchanged words⟩ no default.","type":"number"},"filing_status":{"default":null,"description":"Tax filing status: 'single', 'married', or 'head_of_household'. Optional; matched case-insensitively. Required, with annual_gross_income, for the after-tax comparison.","enum":["single","married","head_of_household",null],"type":["string","null"]},"full_schedule":{"default":null,"description":"Whether ⟨60 unchanged words⟩ {"default":null,"description":"Whether the
Changed the definition of "compare_mortgage_terms"
⟨76 unchanged words⟩ auto-removal tracking per the Homeowners Protection Act, and, when invest_the_difference is on (the default) and filing_status and annual_gross_income are given, an after-tax net worth comparison. Pick this to compare ⟨55 unchanged words⟩
{"properties":{"annual_gross_income":{"default":null,"description":"Annual gross income in dollars, used as adjusted gross income for the tax on investment gains at the horizon. Optional; with filing_status it enables the after-tax comparison. Held at this amount in the year of the assumed investment sale. Must be zero or more and no more than $1,000,000,000.","maximum":1000000000,"minimum":0,"type":["number","null"]},"closing_cost_pct":{"default":null,"description":"Closing ⟨164 unchanged words⟩ 'single', 'married', or 'head_of_household'. Optional; matched case-insensitively. Required, with annual_gross_income, for the after-tax comparison.","enum":["single","married","
Changed the definition of "calculate_loan_payoff", "calculate_refi_breakeven", "compare_debt_consolidation" and 1 more
{"properties":{"annual_rate_pct":{"description":"Loan annualpercentageinterest rate (the note rate in the loan contract, not the disclosed APR, which can differ when fees are financed), e.g. 6.5 not 0.065. Decimal from 0 ⟨181 unchanged words⟩
⟨37 unchanged words⟩ P&I savings; - the cash-flow break-even month (Senaro's formula: total refinance cost divided by monthly savings, rounded up to a whole month, built on the payback test the
Changed the definition of "calculate_cc_payoff"
⟨118 unchanged words⟩ DAY_ZERO_COST, DEBT_GROWING, PROMO_CLIFF, PREDATORY_RATE, SPEND_EXCEEDS_PAYDOWN, PLAN_TERM_ELAPSED_WITH_BALANCE, NO_PAYOFF_WITHIN_PROJECTION), and, separately, validation disclosures emitted as ⟨180 unchanged words⟩ rather than a bare month count: months_to_payoff, card_payoff_order[].payoff_month, min_payments_only.months, minimums_only_baseline.months, and, when windfalls are supplied ⟨24 unchanged words⟩ does not, in which case explanation says why.The per-card payoff month inside card_payoff_order[] does not use the {status, value, explanation} object. It is still a bare integer.
Changed the definition of "calculate_debt_to_income", "compare_debt_consolidation" and "compare_rent_vs_buy"
⟨265 unchanged words⟩ and USDA are each disclosure-only above their baselines - `what_if.scenarios[].qualifies_va` and `changes_qualification_va` are decided on the scenario's unrounded VA ratio rounded to a whole percent under 38 CFR 36.4340(d), not on `new_back_end_dti_va` (two decimals), so a scenario showing 41.44 can qualify; `qualification.va.your_back_end_compared` states the rounded figure VA's row compares with `max_back_end`
⟨564 unchanged words⟩ CONJUNCTIVE: it also requires the back-end debt-to-income ratio, rounded to a whole percent under 38 CFR 36.4340(qualification.va.your_back_endd) (qualification.va.your_back_end_compared), to exceed 41%, which this field does not
Changed the definition of "analyze_cash_advance", "calculate_cc_payoff", "calculate_compound_interest" and 4 more
⟨96 unchanged words⟩ `chart_hints` with rendering directives any client can use.The `senaro-charts` MCP server renders them locally over stdio only.
⟨232 unchanged words⟩ `chart_hints` with rendering directives any client can use.The `senaro-charts` MCP server renders them locally over stdio only.Top-level `entered_starting_balance` echoes the caller's supplied balances by ⟨128 unchanged words⟩
Added "calculate_compound_interest", "calculate_refi_breakeven", "compare_payoff_strategies" and 2 more; removed "compare_strategies", "compound_interest", "payoff_vs_invest" and 2 more; changed the definition of "analyze_cash_advance", "analyze_pmi_removal", "calculate_cc_payoff" and 9 more
⟨27 unchanged words⟩ a valid rate. REQUIRED, no default.","exclusiveMinimum":0,"maximum":100,"type":"number"},"cash_advance_balance":{"description" ⟨66 unchanged words⟩ 100. Optional; defaults to 0 when omitted.","maximum":100,"minimum":0,"type":["number","null"]},"chart_title ⟨10 unchanged words⟩ contain em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]}, ⟨155 unchanged words⟩
Changed the definition of "analyze_pmi_removal", "calculate_cc_payoff", "calculate_debt_to_income" and 10 more
⟨6 unchanged words⟩ professional before acting. Compute every standard PMI-removal pathway: -(HPA automatic at 78% LTV,- HPA borrower-requested at 80% LTV,- optional re-appraisal at a simplified 75% of current ⟨25 unchanged words⟩ 70% for investment and two- to four-unit properties),Also returns current monthly PMI cost, total PMI dollars between ⟨14 unchanged words⟩ the original value) as a lump sum today.Supplying original_loan_term_months and loan_age_months also applies the 12 ⟨20 unchanged words⟩ where HPA applies and the borrower is current.
Changed the definition of "analyze_cash_advance", "analyze_pmi_removal", "calculate_cc_payoff" and 13 more
⟨25 unchanged words⟩ months, and whether the CA is growing. Pick this over `calculate_cc_payoff` when one card's cash advance is the question: it shows how the CARD Act above-minimum allocation rule, 15 U.S.C. §1666c(b)(1), sends payment above the minimum to the highest-APR segment first, which is the cash advance whenever its rate is the higher one. Pick `calculate_cc_payoff` for a payoff timeline across several cards or a windfall schedule. The response includes `chart_hints` with rendering directives any ⟨13 unchanged words⟩
{"properties":{"toolArgumentscash_advance_apr_pct":{"description":"JSONCashobjectadvance
Certificate recorded, valid to 2027-02-05
Authorization not required
First tool surface recorded: 18 tools (server version 1.23.0)
Showing the latest 12 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
⟨61 unchanged words⟩ uses the cited default of 0.67% of theloancurrent balance (LodeStar 2026). An IMMEDIATE break-even requires total upfront cost to be zero(or non-positive)AND monthly_savings to be non-negative AND roll_costs_into_loan false, i.e. closing_costs AND points both 0, not ⟨25 unchanged words⟩ economic (net-worth crossover) break-even. When false,only the cash-flow break-even andeconomic_break_eveninterestreportsdeltaNOT_REQUESTED;areeveryreturned,otherandfieldeconomic_break_evenisreportsstillNOT_REQUESTED.returned. Optional; defaults to true when omitted.","type ⟨72 unchanged words⟩ overrides the formula-derived payment, so match your statement. Rounded to the cent, it must be greater than the first month's interest: current_balance rounded to the cent, times current_annual_rate_pct / 100 / 12, rounded to the cent.","type":["number","null"]} ⟨4 unchanged words⟩ ":"Annual return used for the economic (invest-the-savingsnet-worth crossover) break-even, an EFFECTIVE ANNUALrate;rate: it compounds money not spent on a payment and, when costs are paid upfront, the upfront refinance cost that keeping the current loan leaves invested. The monthly compounding step is (1+pct/100)^(1/12)-1. ⟨76 unchanged words⟩ closing, where 1.0 means 1% of theloan.loan amount: the current balance when costs are paid upfront, or, when roll_costs_into_loan is true, the new loan amount, which includes the financed closing costs and points. Decimal from 0 to 4. Optional; defaults to ⟨34 unchanged words⟩ added to the new principal instead of paidupfront;upfront. When true, points are a percentage of the new loan amount; cash-flow break-eventhenreportsCOSTS_ROLLED_INTO_LOAN.COSTS_ROLLED_INTO_LOAN; and the economic break-even, when requested, compares the two loans with the financed costs in the new principal and no upfront cash. Optional; defaults to false when omitted.","type ⟨10 unchanged words⟩
⟨1141 unchanged words⟩ loan / balance-transfer alternative: 'avalanche' or 'snowball'. In partial consolidation it ranks the loan against the kept cards, and the part it ranks first, the loan or the kept cards, receives the extra payment and any windfalls. Optional; defaults to 'avalanche' when omitted. Case-sensitive."," ⟨38 unchanged words⟩ of the loan's own required payment for consolidation. In partial consolidation, the extra payment and any windfalls go to the part current_strategy ranks first, the loan or the kept cards. Optional; defaults to 0 when omitted. fixed_payments is ⟨214 unchanged words⟩ loan is a single-balance instrument), and onoptimized_consolidation.keep_subset.optimized_consolidation.loan and optimized_consolidation.keep_subset (each windfall dollar is listed once across the two). All scenarios use with-windfalls totals so cross-option ranking ⟨100 unchanged words⟩
⟨1020 unchanged words⟩ omitted. The removal threshold is set by pmi_removal_ltv_pct. Models borrower-paid PMI on a conventional loan; FHA, VA and USDA mortgage insurance is not modeled.","type":["number","null"]} ⟨93 unchanged words⟩ be modeled for any month of the loan. A value just below the initial LTV can also be reached by the first payment; then no month charges PMI either. When the resolved pmi_pct is 0, or down_payment_pct ⟨29 unchanged words⟩ §4902(c)), which this value cannot postpone. Models borrower-paid PMI on a conventional loan; FHA, VA and USDA mortgage insurance is not modeled.","type":["number","null"]} ⟨51 unchanged words⟩ Counted as cash paid at closing on everycall;call.whenWhen apply_tax_benefit is true they are also deducted in year 1, assuming the IRS Pub 936 tests for a first-year deduction are met (main home bought with the loan, points customary and not above the local norm, cash method, not paid in place of separately listed fees, paid with your own money at or before closing, figured as a percentage of the loan and shown as points on the settlement statement), and only for the share the mortgage interest gets: the acquisition-debt limit divided by the year-1 average loan balance, when that is below 1. mortgage_rate_pct must already be the rate these points buy. Optional; defaults to 0 when omitted.","type ⟨213 unchanged words⟩
⟨961 unchanged words⟩ , as a percentage, 0-36, e.g. 10.99. This is the loan's note interest rate, not the disclosed APR. The APR already reflects the origination fee, so entering it here counts the fee twice. Required.","type":["number","null"] ⟨542 unchanged words⟩
⟨78 unchanged words⟩ tax benefit model (Tier-3: apply_tax_benefit=true) withTY2025/TY2026the statute's year-by-year SALTcapscap schedule (advancing with the horizon, not frozen at tax_year), mortgage interest deduction, PMI deductibility, and ⟨68 unchanged words⟩
before
{"properties":{"age_65_plus_count":{"default":null,"description":"Number of filers aged 65 or older, each adding the additional standard deduction. Integer from 0 to 2. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["integer","null"]},"annual_gross_income":{"default":null,"description":"Annual gross income, the MAGI proxy for the bracket and the SALT cap. Decimal from 0 to 1,000,000,000. Required when apply_tax_benefit is true; otherwise not used.","type":["number","null"]},"apply_tax_benefit":{"default":null,"description":"Whether to apply the federal tax benefit model (TY2025/TY2026 SALT caps, mortgage interest deduction, PMI deductibility). When true, filing_status, tax_year and annual_gross_income are required. Optional; defaults to false when omitted. The §121 home-sale gain exclusion applies only at sale points 24 months or more after purchase (IRC §121(a) 2-of-5-year test); year 1 of yearly_series, months 1-23 in monthly_series, and any horizon under 24 months use no exclusion. Separately, IRC §1222(3) makes a holding period of 12 months or less short-term, taxed at ordinary rates instead of the long-term rates otherwise applied, on the home-sale gain and the renter's portfolio gain alike (24 months vs. 12 months are two different thresholds); this tool applies that split exactly to the home-sale gain, and to the renter's portfolio at annual grain: prior years' contributions are compounded together as one long-term lot rather than aged individually, so months inside a year understate short-term gain.","type":["boolean","null"]},"basis_capitalizable_pct_override":{"default":null,"description":"Percentage of the buy-side closing cost that is capitalizable into the §121 adjusted basis (IRS Pub 523 split: abstract fees, title search, recording fees, survey fees, transfer taxes, owner's title insurance). Decimal from 0 to 100; 0 means a HomePrice-only basis, 100 means the full closing cost is in basis. Optional; defaults to 50% (Senaro deterministic midpoint) when omitted. Supply your actual HUD-1 split when available.","type":["number","null"]},"blind_count":{"default":null,"description":"Number of blind filers, each adding the additional standard deduction. Integer from 0 to 2. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["integer","null"]},"charitable":{"default":null,"description":"Charitable contributions. Decimal from 0 to 1,000,000,000; TY2026 and later apply a 0.5%-of-AGI floor per OBBBA §70425. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"chart_title":{"default":null,"description":"Override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"down_payment_pct":{"default":null,"description":"Down payment as a percentage of the home price. Decimal from 0 to 100; 0 is valid (zero-down programs). Optional; defaults to 20% when omitted.","type":["number","null"]},"filing_status":{"default":null,"description":"Tax filing status: 'Single', 'MFJ', 'MFS' or 'HoH'. Required when apply_tax_benefit is true; otherwise not used.","type":["string","null"]},"hoa_monthly":{"default":null,"description":"Monthly HOA dues on the BUY path. Decimal from 0 to 1,000,000,000. Optional; defaults to 0 when omitted.","type":["number","null"]},"home_appreciation_pct":{"default":null,"description":"Annual home price appreciation as a percentage. Decimal from -50 to 50. Optional; defaults to the cited 4.25% (FHFA HPI) when omitted; override for your market.","type":["number","null"]},"home_insurance_pct":{"default":null,"description":"Annual home insurance as a percentage of home value. Decimal from 0 to 15. Optional; defaults to 0.65% when omitted; override for your market.","type":["number","null"]},"home_price":{"description":"Home purchase price. Decimal, greater than 0 and at most 1,000,000,000. REQUIRED, no default.","type":"number"},"horizon_years":{"default":null,"description":"Projection horizon in years. Integer from 1 to 40. Optional; when omitted, the response returns snapshots at years 5, 10 and 30.","type":["integer","null"]},"inflation_pct":{"default":null,"description":"Inflation as a percentage, for the real_terms toggle. Decimal, at least 0 and less than 100. Optional; when omitted, a nominal run uses 2.5%, and a real_terms run uses the horizon-based default: 2.0% for a horizon of 7 years or less, 2.6% for 8 to 19 years, 2.5% for 20 years or more.","type":["number","null"]},"investment_return_pct":{"default":null,"description":"RENT path annual return as a percentage, an EFFECTIVE ANNUAL rate; the monthly compounding step is (1+pct/100)^(1/12)-1. Decimal from -50 to 30. Optional; defaults to 10.0% when omitted.","type":["number","null"]},"loan_origination_date":{"default":null,"description":"Mortgage origination date, YYYY-MM-DD. Selects the mortgage interest deduction cap: on or before 2017-12-15 the $1M cap, after it the $750k cap (Single and MFJ; MFS caps are half). Only used when apply_tax_benefit is true. Optional; omitting it uses the post-2017 cap.","type":["string","null"]},"loan_term_months":{"default":null,"description":"Mortgage term in months. Integer from 1 to 480. Optional; defaults to 360 (a 30-year fixed) when omitted.","type":["integer","null"]},"maintenance_pct":{"default":null,"description":"Annual maintenance as a percentage of home value. Decimal from 0 to 20. Optional; defaults to the cited 1.5% (Harvard JCHS) when omitted; override for your market.","type":["number","null"]},"monthly_rent":{"description":"Monthly rent on the RENT path. Decimal from 0 to 1,000,000,000; 0 is valid (a free-housing baseline). REQUIRED, no default.","type":"number"},"mortgage_rate_pct":{"description":"Mortgage annual rate as a percentage, e.g. 6.75 for 6.75%. Decimal, greater than 0 and at most 100. Never cached; provide the current rate. REQUIRED, no default.","type":"number"},"other_itemizable":{"default":null,"description":"Other itemizable deductions, such as medical expenses above 7.5% of AGI or casualty losses. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"output":{"description":"Valid values: 'summary' (default), 'inline'. 'summary' returns headline scalars and per-horizon snapshots with the heavy series stripped. 'inline' returns the full payload including yearly_series[] and monthly_series[] for chart rendering.","enum":["summary","inline",null],"type":["string","null"]},"pmi_annual":{"default":null,"description":"Annual PMI premium in dollars while PMI is active. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; when omitted it is derived from pmi_pct and the original loan amount.","type":["number","null"]},"pmi_pct":{"default":null,"description":"Annual PMI rate as a percentage of the loan. Decimal from 0 to 5. Optional; defaults to 0.5% when omitted. The removal threshold is set by pmi_removal_ltv_pct.","type":["number","null"]},"pmi_removal_ltv_pct":{"default":null,"description":"Loan-balance trigger for PMI removal, as a percentage loan-to-value. Decimal from 50 to 100. Optional; omitted, it is the 78% HPA automatic-termination threshold; provided (e.g. 80), it is whichever of 78% or your value is reached first. The rejection guard applies only when down_payment_pct is below 20 and the resolved pmi_pct is above 0, the range where PMI applies: there, a value at or above the loan's own initial LTV is rejected, because the requested removal point would already be met at the first payment, so no PMI would be modeled for any month of the loan. When the resolved pmi_pct is 0, or down_payment_pct is 20 or more, no such check runs, whatever the LTV. Either way PMI also stops at the statutory amortization midpoint of the original term (12 U.S.C. §4901(7), §4902(c)), which this value cannot postpone.","type":["number","null"]},"property_tax_pct":{"default":null,"description":"Annual property tax as a percentage of home value. Decimal from 0 to 10. Optional; defaults to 0.88% when omitted; override for your market.","type":["number","null"]},"purchase_year_points":{"default":null,"description":"Discount points paid at origination, as a percentage of the loan. Decimal from 0 to 4. Counted as cash paid at closing on every call; when apply_tax_benefit is true they are also deducted in year 1. Optional; defaults to 0 when omitted.","type":["number","null"]},"real_terms":{"default":null,"description":"Whether to deflate the output series to a real-terms view. Optional; defaults to false when omitted.","type":["boolean","null"]},"rent_growth_pct":{"default":null,"description":"Annual rent escalation as a percentage. Decimal from -50 to 50. Optional; defaults to the cited 3.4% (BLS CPI ROPR) when omitted; override for your market.","type":["number","null"]},"sell_side_pct":{"default":null,"description":"Sell-side transaction cost as a percentage of the sale price. Decimal from 0 to 25. Optional; defaults to the cited 7.5% (Redfin post-NAR) when omitted; override for your market.","type":["number","null"]},"state_local_tax":{"default":null,"description":"State and local tax paid (state income or sales tax), for the SALT cap. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"tax_year":{"default":null,"description":"Tax year: 2025 or 2026. Integer. Required when apply_tax_benefit is true; otherwise not used.","type":["integer","null"]}},"required":["home_price","monthly_rent","mortgage_rate_pct"],"type":"object"}after
{"properties":{"age_65_plus_count":{"default":null,"description":"Number of filers aged 65 or older, each adding the additional standard deduction. Integer from 0 to 2. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["integer","null"]},"annual_gross_income":{"default":null,"description":"Annual gross income, the MAGI proxy for the bracket and the SALT cap. Decimal from 0 to 1,000,000,000. Required when apply_tax_benefit is true; otherwise not used.","type":["number","null"]},"apply_tax_benefit":{"default":null,"description":"Whether to apply the federal tax benefit model (SALT cap following the statute's year-by-year schedule, mortgage interest deduction, PMI deductibility). When true, filing_status, tax_year and annual_gross_income are required. Optional; defaults to false when omitted. The §121 home-sale gain exclusion applies only at sale points 24 months or more after purchase (IRC §121(a) 2-of-5-year test); year 1 of yearly_series, months 1-23 in monthly_series, and any horizon under 24 months use no exclusion. Separately, IRC §1222(3) makes a holding period of 12 months or less short-term, taxed at ordinary rates instead of the long-term rates otherwise applied, on the home-sale gain and the renter's portfolio gain alike (24 months vs. 12 months are two different thresholds); this tool applies that split exactly to the home-sale gain, and to the renter's portfolio at annual grain: prior years' contributions are compounded together as one long-term lot rather than aged individually, so months inside a year understate short-term gain.","type":["boolean","null"]},"basis_capitalizable_pct_override":{"default":null,"description":"Percentage of the buy-side closing cost that is capitalizable into the §121 adjusted basis (IRS Pub 523 split: abstract fees, title search, recording fees, survey fees, transfer taxes, owner's title insurance). Decimal from 0 to 100; 0 means a HomePrice-only basis, 100 means the full closing cost is in basis. Optional; defaults to 50% (Senaro deterministic midpoint) when omitted. Supply your actual HUD-1 split when available.","type":["number","null"]},"blind_count":{"default":null,"description":"Number of blind filers, each adding the additional standard deduction. Integer from 0 to 2. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["integer","null"]},"charitable":{"default":null,"description":"Charitable contributions. Decimal from 0 to 1,000,000,000; TY2026 and later apply a 0.5%-of-AGI floor per OBBBA §70425. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"chart_title":{"default":null,"description":"Override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"down_payment_pct":{"default":null,"description":"Down payment as a percentage of the home price. Decimal from 0 to 100; 0 is valid (zero-down programs). Optional; defaults to 20% when omitted.","type":["number","null"]},"filing_status":{"default":null,"description":"Tax filing status: 'Single', 'MFJ', 'MFS' or 'HoH'. Required when apply_tax_benefit is true; otherwise not used.","type":["string","null"]},"hoa_monthly":{"default":null,"description":"Monthly HOA dues on the BUY path. Decimal from 0 to 1,000,000,000. Optional; defaults to 0 when omitted.","type":["number","null"]},"home_appreciation_pct":{"default":null,"description":"Annual home price appreciation as a percentage. Decimal from -50 to 50. Optional; defaults to the cited 4.25% (FHFA HPI) when omitted; override for your market.","type":["number","null"]},"home_insurance_pct":{"default":null,"description":"Annual home insurance as a percentage of home value. Decimal from 0 to 15. Optional; defaults to 0.65% when omitted; override for your market.","type":["number","null"]},"home_price":{"description":"Home purchase price. Decimal, greater than 0 and at most 1,000,000,000. REQUIRED, no default.","type":"number"},"horizon_years":{"default":null,"description":"Projection horizon in years. Integer from 1 to 40. Optional; when omitted, the response returns snapshots at years 5, 10 and 30.","type":["integer","null"]},"inflation_pct":{"default":null,"description":"Inflation as a percentage, for the real_terms toggle. Decimal, at least 0 and less than 100. Optional; when omitted, a nominal run uses 2.5%, and a real_terms run uses the horizon-based default: 2.0% for a horizon of 7 years or less, 2.6% for 8 to 19 years, 2.5% for 20 years or more.","type":["number","null"]},"investment_return_pct":{"default":null,"description":"RENT path annual return as a percentage, an EFFECTIVE ANNUAL rate; the monthly compounding step is (1+pct/100)^(1/12)-1. Decimal from -50 to 30. Optional; defaults to 10.0% when omitted.","type":["number","null"]},"loan_origination_date":{"default":null,"description":"Mortgage origination date, YYYY-MM-DD. Selects the mortgage interest deduction cap: on or before 2017-12-15 the $1M cap, after it the $750k cap (Single and MFJ; MFS caps are half). Only used when apply_tax_benefit is true. Optional; omitting it uses the post-2017 cap.","type":["string","null"]},"loan_term_months":{"default":null,"description":"Mortgage term in months. Integer from 1 to 480. Optional; defaults to 360 (a 30-year fixed) when omitted.","type":["integer","null"]},"maintenance_pct":{"default":null,"description":"Annual maintenance as a percentage of home value. Decimal from 0 to 20. Optional; defaults to the cited 1.5% (Harvard JCHS) when omitted; override for your market.","type":["number","null"]},"monthly_rent":{"description":"Monthly rent on the RENT path. Decimal from 0 to 1,000,000,000; 0 is valid (a free-housing baseline). REQUIRED, no default.","type":"number"},"mortgage_rate_pct":{"description":"Mortgage annual rate as a percentage, e.g. 6.75 for 6.75%. Decimal, greater than 0 and at most 100. Never cached; provide the current rate. REQUIRED, no default.","type":"number"},"other_itemizable":{"default":null,"description":"Other itemizable deductions, such as medical expenses above 7.5% of AGI or casualty losses. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"output":{"description":"Valid values: 'summary' (default), 'inline'. 'summary' returns headline scalars and per-horizon snapshots with the heavy series stripped. 'inline' returns the full payload including yearly_series[] and monthly_series[] for chart rendering.","enum":["summary","inline",null],"type":["string","null"]},"pmi_annual":{"default":null,"description":"Annual PMI premium in dollars while PMI is active. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; when omitted it is derived from pmi_pct and the original loan amount.","type":["number","null"]},"pmi_pct":{"default":null,"description":"Annual PMI rate as a percentage of the loan. Decimal from 0 to 5. Optional; defaults to 0.5% when omitted. The removal threshold is set by pmi_removal_ltv_pct.","type":["number","null"]},"pmi_removal_ltv_pct":{"default":null,"description":"Loan-balance trigger for PMI removal, as a percentage loan-to-value. Decimal from 50 to 100. Optional; omitted, it is the 78% HPA automatic-termination threshold; provided (e.g. 80), it is whichever of 78% or your value is reached first. The rejection guard applies only when down_payment_pct is below 20 and the resolved pmi_pct is above 0, the range where PMI applies: there, a value at or above the loan's own initial LTV is rejected, because the requested removal point would already be met at the first payment, so no PMI would be modeled for any month of the loan. When the resolved pmi_pct is 0, or down_payment_pct is 20 or more, no such check runs, whatever the LTV. Either way PMI also stops at the statutory amortization midpoint of the original term (12 U.S.C. §4901(7), §4902(c)), which this value cannot postpone.","type":["number","null"]},"property_tax_pct":{"default":null,"description":"Annual property tax as a percentage of home value. Decimal from 0 to 10. Optional; defaults to 0.88% when omitted; override for your market.","type":["number","null"]},"purchase_year_points":{"default":null,"description":"Discount points paid at origination, as a percentage of the loan. Decimal from 0 to 4. Counted as cash paid at closing on every call; when apply_tax_benefit is true they are also deducted in year 1. Optional; defaults to 0 when omitted.","type":["number","null"]},"real_terms":{"default":null,"description":"Whether to deflate the output series to a real-terms view. Optional; defaults to false when omitted.","type":["boolean","null"]},"rent_growth_pct":{"default":null,"description":"Annual rent escalation as a percentage. Decimal from -50 to 50. Optional; defaults to the cited 3.4% (BLS CPI ROPR) when omitted; override for your market.","type":["number","null"]},"sell_side_pct":{"default":null,"description":"Sell-side transaction cost as a percentage of the sale price. Decimal from 0 to 25. Optional; defaults to the cited 7.5% (Redfin post-NAR) when omitted; override for your market.","type":["number","null"]},"state_local_tax":{"default":null,"description":"State and local tax paid (state income or sales tax), for the SALT cap. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"tax_year":{"default":null,"description":"Tax year for year 1 of the horizon: 2025 or 2026. Integer. Required when apply_tax_benefit is true; otherwise not used. Horizon year y uses tax year (tax_year + y - 1) on both the tax benefit and the sale-side capital-gains tax; the SALT cap follows the statute's own schedule for that year, and every other indexed amount holds at its last-loaded table value beyond it.","type":["integer","null"]}},"required":["home_price","monthly_rent","mortgage_rate_pct"],"type":"object"}⟨60 unchanged words⟩ `chart_hints` with rendering directives any client can use.The `senaro-charts` MCP server renders them locally over stdio only.
⟨133 unchanged words⟩ `chart_hints` with rendering directives any client can use.The `senaro-charts` MCP server renders them locally over stdio only.This tool does not support output: 'inline' on any transport.
⟨64 unchanged words⟩ `chart_hints` with rendering directives any client can use.The `senaro-charts` MCP server renders them locally over stdio only.
⟨147 unchanged words⟩ `chart_hints` with rendering directives any client can use.The `senaro-charts` MCP server renders them locally over stdio only.HEAVY tool: use output='summary' (default) for ⟨9 unchanged words⟩
⟨376 unchanged words⟩ `chart_hints` with rendering directives any client can use.The `senaro-charts` MCP server renders them locally over stdio only.This tool takes no strategy, fixed_payments, full_schedule ⟨20 unchanged words⟩
⟨130 unchanged words⟩ applies and the borrower is current. Pairs with`refi_breakeven``calculate_refi_breakeven` for a refinance's rate-and-term break-even, and with ⟨26 unchanged words⟩
⟨68 unchanged words⟩ em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"current_balance ⟨5 unchanged words⟩ greater than 0. REQUIRED, no default.","minimum":0.01,"type":"number"},"current_home_value":{"default" ⟨46 unchanged words⟩ market value with a fresh appraisal).","minimum":0.01,"type":["number","null"]},"extra_monthly_payment ⟨75 unchanged words⟩ greater than 0. REQUIRED, no default.","minimum":0.01,"type":"number"},"original_appraised_value":{"default" ⟨37 unchanged words⟩ appraisal came in below the purchase price.","minimum":0.01,"type":["number","null"]},"original_loan_term_months ⟨93 unchanged words⟩ Decimal, greater than 0. REQUIRED, no default.","minimum":0.01,"type":"number"}},"required":[ ⟨6 unchanged words⟩
⟨9 unchanged words⟩ Calculate credit card payoff timeline with month-by-month amortization. Pick this for a payoff timeline across credit cards under one strategy, including windfalls or fixed payments; pick `compare_payoff_strategies` to compare avalanche against snowball, `calculate_loan_payoff` for a single installment loan, and `analyze_cash_advance` when one card's cash advance is the question. Supports dual APR segments (purchase + cash advance ⟨321 unchanged words⟩
before
{"properties":{"apply_rate_cap":{"default":null,"description":"Whether to cap each card's APR at the regulatory ceiling before simulating. Optional; defaults to false when omitted.","type":["boolean","null"]},"cards":{"description":"Credit cards to pay off, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards is required and must be an array.\"); the two are not the same rejection. Every card may carry segments[]. Max 100 segments total across all cards in the request. Per-card, per-type caps: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan.","items":{"properties":{"annual_fee":{"description":"Annual fee in dollars, $0 to $1,000,000,000. Optional; defaults to 0. Charged at month 1 and every twelfth month after, while the card carries a balance.","type":["number","null"]},"cash_advance_apr_pct":{"description":"Cash advance APR as a percentage, greater than 0 and up to 100. Required when cash_advance_balance is greater than 0: cash advances have no promotional 0% product, so a 0% rate on a real advance balance is a data-entry error.","type":["number","null"]},"cash_advance_balance":{"description":"Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted. A POSITIVE value alongside a non-empty segments[] is rejected, the same way purchase_balance is. An explicit 0 is accepted.","type":["number","null"]},"minimum_payment":{"description":"Minimum payment in dollars, $0 to $1,000,000,000 (optional, omit or set 0 to auto-calculate). Where it binds, the card is locked at max(minimum_payment, that card's issuer minimum computed at month 1), and that locked amount is paid every month. On calculate_cc_payoff it binds ONLY when fixed_payments = true; on the DEFAULT path (fixed_payments = false) it is NOT used, because the plan recomputes each card's issuer minimum from its current balance every month, and the response discloses that as MINIMUM_PAYMENT_NOT_BINDING. On compare_strategies there is no fixed_payments parameter and supplying one is rejected: the avalanche and snowball arms ALWAYS run locked, so the value DOES bind and moves both arms, while the minimum-payments-only baseline always recomputes and ignores it, disclosed as MINIMUM_PAYMENT_NOT_BINDING_IN_BASELINE.","type":["number","null"]},"monthly_spend":{"description":"Recurring monthly purchase amount charged to this card's purchase balance before interest accrues, $0 to $50,000 per month. Optional; defaults to 0. Use the segment-level monthly_spend instead when supplying segments[].","type":["number","null"]},"name":{"description":"Card label, e.g. 'Chase Sapphire', 120 characters or fewer. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', and so on). Echoed into per-card results and warning text. A name over the cap is replaced in error field paths by a key built from its zero-based card index, written as '#0 (name over cap)', '#1 (name over cap)' and so on.","type":["string","null"]},"plan_fees_monthly":{"description":"Recurring monthly card fee in dollars, $0 to $1,000,000,000, e.g. a pay-over-time plan fee. Optional; defaults to 0. Charged every month while the card carries a balance.","type":["number","null"]},"purchase_apr_pct":{"description":"Purchase APR as a percentage, 0 to 100, e.g. 24.99 not 0.2499. Required when purchase_balance is greater than 0: an omitted APR would silently compute $0 interest.","type":["number","null"]},"purchase_balance":{"description":"Purchase balance in dollars, $0 to $1,000,000,000. Required unless segments[] carries at least one segment: an omitted purchase_balance would silently report a $0, 0-month payoff. Supplying a POSITIVE value alongside a non-empty segments[] is rejected, since the two would be competing sources for the same balance. An explicit 0 is accepted.","type":["number","null"]},"segments":{"description":"Per-segment breakdown of this card's balances. Optional; when it carries at least one segment it SUPERSEDES purchase_balance and cash_advance_balance, and a POSITIVE value in either of those is rejected. An empty segments[] is treated as absent, so purchase_balance is then required. At most 100 segments across the whole request. Per card, per type: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan. Each item carries its own type, balance, rate and payment priority; see the type field on the item for the per-type field matrix.","items":{"properties":{"apr_pct":{"default":null,"description":"Annual percentage rate for this segment, 0 to 100, e.g. 24.99 not 0.2499. Required when balance is greater than 0 on purchase, cash_advance, balance_transfer and promotional. On cash_advance it must be greater than 0 whenever a balance is carried. Must be 0 on installment_plan, which uses monthly_fee instead, so omitting it there is the correct shape.","type":["number","null"]},"balance":{"description":"Segment balance in dollars, $0 to $1,000,000,000. REQUIRED on every segment type: an omitted balance would silently report a $0, 0-month payoff, so it is rejected instead. An explicit 0 is valid, for example a paid-off balance_transfer segment kept for schedule continuity.","type":"number"},"extra_payment_order":{"default":null,"description":"Extra-payment tie-break priority, 0 or more, where 0 means this segment never receives extra payment. Optional on every type, and the default for installment_plan. Only breaks a tie between segments sharing the exact same current APR, since the Credit CARD Act (TILA §164(b), 15 U.S.C. §1666c(b)) / 12 CFR 1026.53(a) always pays the highest-current-APR segment first regardless of this value.","type":["integer","null"]},"merchant_name":{"default":null,"description":"Label for an installment plan's merchant, 120 characters or fewer. Optional on installment_plan, ignored on every other type.","type":["string","null"]},"min_payment_order":{"default":null,"description":"Minimum-payment tie-break priority, 1 or more. Optional on every type. The minimum first pays any installment_plan's locked plan_payment_due in full, then the lowest-current-APR segment; this value only breaks a tie between segments sharing both the same current APR and the same installment-plan status.","type":["integer","null"]},"monthly_fee":{"default":null,"description":"Fixed fee charged each month while an installment plan's term is active, $0 or more and no greater than plan_payment_due. Optional on installment_plan. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"monthly_spend":{"default":null,"description":"Recurring monthly purchase amount posted to this segment before interest accrues, $0 to $50,000 per month. Optional on purchase. A negative value is rejected as NEGATIVE_BALANCE on every type. On every type other than purchase a positive value is rejected with FIELD_NOT_ALLOWED_HERE, since those balances do not accept new purchases; an explicit 0 is accepted.","type":["number","null"]},"plan_payment_due":{"default":null,"description":"Locked monthly payment for an installment plan, principal plus monthly_fee. Required on installment_plan, greater than $0, at least monthly_fee, and no more than $1,000,000,000. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"promo_expires_month":{"default":null,"description":"Month at which apr_pct flips to revert_apr_pct, 1 to 480. Required on balance_transfer and promotional. Ignored on purchase, cash_advance and installment_plan.","type":["integer","null"]},"remaining_payments":{"default":null,"description":"Payments left in an installment plan's stated term, 0 or more. Optional on installment_plan, ignored on every other type. 0 means the term has ALREADY ended and is valid with any balance, including a positive residual. From 1 up, the balance must be clearable within the stated term and must not be clearable a month early.","type":["integer","null"]},"revert_apr_pct":{"default":null,"description":"Rate this segment reverts to once its promo expires, 0 to 100, and at least apr_pct. Required on balance_transfer and promotional. Ignored on purchase and cash_advance. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate rather than repricing.","type":["number","null"]},"stop_spend_month":{"default":null,"description":"Month index at which recurring spend stops, 0 or more. Read on purchase only, and range checked on every type. Omit to spend for the whole projection.","type":["integer","null"]},"type":{"description":"Segment type. REQUIRED on every segment: omitting it is rejected. Per-type field matrix. Every field below is classified for every segment type: REQUIRED (omitting it is rejected), OPTIONAL (accepted either way and read), IGNORED (accepted and never read for this type, though a value can still fail the field's own range check), or REJECTED (supplying a disallowed value is an error; the field's own rule below says exactly which values are disallowed). Value rules are stated separately from applicability, because a field can be accepted on a type and still be restricted there. The validators are the authority; this matrix describes them.\n- type: REQUIRED on every type. Values: one of purchase, cash_advance, balance_transfer, promotional, installment_plan.\n- balance: REQUIRED on every type. Values: $0 to $1,000,000,000; above $50,000 returns a HIGH_CARD_BALANCE warning, not an error.\n- apr_pct: REQUIRED on purchase, cash_advance, balance_transfer, promotional; OPTIONAL on installment_plan. Values: 0 to 100 as a percentage, e.g. 24.99 not 0.2499. The REQUIRED classification above applies when balance is greater than 0; a zero-balance segment may omit it. Must be greater than 0 on cash_advance carrying a balance. Must equal 0 on installment_plan, where omitting it is the correct shape.\n- revert_apr_pct: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance; REJECTED on installment_plan. Values: 0 to 100, and at least apr_pct. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate.\n- promo_expires_month: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance, installment_plan. Values: 1 to 480.\n- monthly_fee: OPTIONAL on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: $0 or more, and no greater than plan_payment_due, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- plan_payment_due: REQUIRED on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: greater than $0, at least monthly_fee, and no more than $1,000,000,000, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- remaining_payments: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 0 or more. 0 means the stated term has ALREADY ended and is valid with any balance. From 1 up, balance must be clearable within the stated term.\n- min_payment_order: OPTIONAL on every type. Values: 1 or more; breaks a tie only between segments sharing both the same current APR and the same installment-plan status.\n- extra_payment_order: OPTIONAL on every type. Values: 0 or more; 0 means skip. Breaks a tie only between segments sharing the exact same current APR.\n- merchant_name: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 120 characters or fewer.\n- monthly_spend: OPTIONAL on purchase; REJECTED on cash_advance, balance_transfer, promotional, installment_plan. Values: $0 to $50,000 per month. A negative value is rejected as NEGATIVE_BALANCE on every type, purchase included. On every type other than purchase a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; an explicit 0 is accepted.\n- stop_spend_month: OPTIONAL on purchase; IGNORED on cash_advance, balance_transfer, promotional, installment_plan. Values: 0 or more; range checked on every type, read only on purchase.","type":"string"}},"required":["type","balance"],"type":"object"},"type":["array","null"]},"stop_spend_month":{"description":"Month index at which this card's recurring spend stops, 0 or more. Optional; omit to spend for the whole projection.","type":["integer","null"]}},"type":"object"},"type":"array"},"chart_title":{"default":null,"description":"Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.","type":["string","null"]},"extra_monthly_payment":{"default":null,"description":"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums. Optional; defaults to 0 when omitted.","type":["number","null"]},"fixed_payments":{"default":null,"description":"Whether to hold each card's payment constant for the whole payoff. Optional; defaults to false when omitted. When true, each card's payment is locked at max(cards[].minimum_payment, that card's issuer minimum computed at month 1), and the total monthly budget (those locked amounts plus extra_monthly_payment) is held constant for the whole payoff, so once a card is paid off its freed-up payment rolls forward onto the remaining cards. This is the ONLY mode in which cards[].minimum_payment affects calculate_cc_payoff's result; compare_strategies has no fixed_payments parameter and binds minimum_payment on both of its strategy arms regardless.","type":["boolean","null"]},"full_schedule":{"default":null,"description":"Whether to return the full per-card month-by-month schedule. Optional; defaults to false when omitted. The per-card monthly_schedule is capped at 1000 rows total across cards and months, so later months are omitted on a long multi-card payoff; the portfolio-level monthly_totals series is always complete and is the one to read for the whole timeline.","type":["boolean","null"]},"include_card_timeline":{"default":null,"description":"Whether to add the card_timeline block, a per-card view of when each card clears. Optional; defaults to false when omitted.","type":["boolean","null"]},"output":{"description":"Valid values: 'summary' (default), 'inline'. summary returns a compact response with a data_preview block; inline returns the full payload.","enum":["summary","inline"],"type":"string"},"per_segment":{"default":null,"description":"Whether each schedule row carries its per-segment breakdown. Optional; defaults to true when omitted.","type":["boolean","null"]},"strategy":{"default":null,"description":"Payoff order: 'avalanche' pays the highest APR first, 'snowball' the smallest balance first. Optional; defaults to 'avalanche' when omitted. Matched case-insensitively, and the response echoes the canonical lowercase form actually simulated.","type":["string","null"]},"windfalls":{"default":null,"description":"One-time principal payments, at most 12, e.g. a tax refund or a year-end bonus. Optional; a JSON null is treated as omitted. When non-empty the response gains baseline, with_windfalls, months_saved_vs_baseline, interest_saved_vs_baseline, windfalls_applied[] and windfalls_unused[]; an empty array returns the same shape as omitting it.","items":{"properties":{"amount":{"description":"Dollar amount of the windfall, greater than 0. Required per entry.","type":["number","null"]},"label":{"description":"Optional label for this windfall, e.g. 'Tax refund' or 'Year-end bonus'. Max 120 characters.","type":["string","null"]},"month":{"description":"Month index the windfall is applied, 0 or more. 0 means applied before month 1's interest; N >= 1 applies at the end of calendar month N. Required per entry.","type":["integer","null"]}},"type":["object","null"]},"type":["array","null"]}},"required":["cards"],"type":"object"}after
{"properties":{"apply_rate_cap":{"default":null,"description":"Whether to cap each card's APR at the regulatory ceiling before simulating. Optional; defaults to false when omitted.","type":["boolean","null"]},"cards":{"description":"Credit cards to pay off, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards is required and must be an array.\"); the two are not the same rejection. Every card may carry segments[]. Max 100 segments total across all cards in the request. Per-card, per-type caps: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan.","items":{"properties":{"annual_fee":{"description":"Annual fee in dollars, $0 to $1,000,000,000. Optional; defaults to 0. Charged at month 1 and every twelfth month after, while the card carries a balance.","type":["number","null"]},"cash_advance_apr_pct":{"description":"Cash advance APR as a percentage, greater than 0 and up to 100. Required when cash_advance_balance is greater than 0: cash advances have no promotional 0% product, so a 0% rate on a real advance balance is a data-entry error.","type":["number","null"]},"cash_advance_balance":{"description":"Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted. A POSITIVE value alongside a non-empty segments[] is rejected, the same way purchase_balance is. An explicit 0 is accepted.","type":["number","null"]},"minimum_payment":{"description":"Minimum payment in dollars, $0 to $1,000,000,000 (optional, omit or set 0 to auto-calculate). Where it binds, the card is locked at max(minimum_payment, that card's issuer minimum computed at month 1), and that locked amount is paid every month. On calculate_cc_payoff it binds ONLY when fixed_payments = true; on the DEFAULT path (fixed_payments = false) it is NOT used, because the plan recomputes each card's issuer minimum from its current balance every month, and the response discloses that as MINIMUM_PAYMENT_NOT_BINDING. On compare_payoff_strategies there is no fixed_payments parameter and supplying one is rejected: the avalanche and snowball arms ALWAYS run locked, so the value DOES bind and moves both arms, while the minimum-payments-only baseline always recomputes and ignores it, disclosed as MINIMUM_PAYMENT_NOT_BINDING_IN_BASELINE.","type":["number","null"]},"monthly_spend":{"description":"Recurring monthly purchase amount charged to this card's purchase balance before interest accrues, $0 to $50,000 per month. Optional; defaults to 0. Use the segment-level monthly_spend instead when supplying segments[].","type":["number","null"]},"name":{"description":"Card label, e.g. 'Chase Sapphire', 120 characters or fewer. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', and so on). Echoed into per-card results and warning text. A name over the cap is replaced in error field paths by a key built from its zero-based card index, written as '#0 (name over cap)', '#1 (name over cap)' and so on.","maxLength":120,"type":["string","null"]},"plan_fees_monthly":{"description":"Recurring monthly card fee in dollars, $0 to $1,000,000,000, e.g. a pay-over-time plan fee. Optional; defaults to 0. Charged every month while the card carries a balance.","type":["number","null"]},"purchase_apr_pct":{"description":"Purchase APR as a percentage, 0 to 100, e.g. 24.99 not 0.2499. Required when purchase_balance is greater than 0: an omitted APR would silently compute $0 interest.","maximum":100,"minimum":0,"type":["number","null"]},"purchase_balance":{"description":"Purchase balance in dollars, $0 to $1,000,000,000. Required unless segments[] carries at least one segment: an omitted purchase_balance would silently report a $0, 0-month payoff. Supplying a POSITIVE value alongside a non-empty segments[] is rejected, since the two would be competing sources for the same balance. An explicit 0 is accepted.","type":["number","null"]},"segments":{"description":"Per-segment breakdown of this card's balances. Optional; when it carries at least one segment it SUPERSEDES purchase_balance and cash_advance_balance, and a POSITIVE value in either of those is rejected. An empty segments[] is treated as absent, so purchase_balance is then required. At most 100 segments across the whole request. Per card, per type: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan. Each item carries its own type, balance, rate and payment priority; see the type field on the item for the per-type field matrix.","items":{"properties":{"apr_pct":{"default":null,"description":"Annual percentage rate for this segment, 0 to 100, e.g. 24.99 not 0.2499. Required when balance is greater than 0 on purchase, cash_advance, balance_transfer and promotional. On cash_advance it must be greater than 0 whenever a balance is carried. Must be 0 on installment_plan, which uses monthly_fee instead, so omitting it there is the correct shape.","type":["number","null"]},"balance":{"description":"Segment balance in dollars, $0 to $1,000,000,000. REQUIRED on every segment type: an omitted balance would silently report a $0, 0-month payoff, so it is rejected instead. An explicit 0 is valid, for example a paid-off balance_transfer segment kept for schedule continuity.","type":"number"},"extra_payment_order":{"default":null,"description":"Extra-payment tie-break priority, 0 or more, where 0 means this segment never receives extra payment. Optional on every type, and the default for installment_plan. Only breaks a tie between segments sharing the exact same current APR, since the Credit CARD Act (TILA §164(b), 15 U.S.C. §1666c(b)) / 12 CFR 1026.53(a) always pays the highest-current-APR segment first regardless of this value.","type":["integer","null"]},"merchant_name":{"default":null,"description":"Label for an installment plan's merchant, 120 characters or fewer. Optional on installment_plan, ignored on every other type.","type":["string","null"]},"min_payment_order":{"default":null,"description":"Minimum-payment tie-break priority, 1 or more. Optional on every type. The minimum first pays any installment_plan's locked plan_payment_due in full, then the lowest-current-APR segment; this value only breaks a tie between segments sharing both the same current APR and the same installment-plan status.","type":["integer","null"]},"monthly_fee":{"default":null,"description":"Fixed fee charged each month while an installment plan's term is active, $0 or more and no greater than plan_payment_due. Optional on installment_plan. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"monthly_spend":{"default":null,"description":"Recurring monthly purchase amount posted to this segment before interest accrues, $0 to $50,000 per month. Optional on purchase. A negative value is rejected as NEGATIVE_BALANCE on every type. On every type other than purchase a positive value is rejected with FIELD_NOT_ALLOWED_HERE, since those balances do not accept new purchases; an explicit 0 is accepted.","type":["number","null"]},"plan_payment_due":{"default":null,"description":"Locked monthly payment for an installment plan, principal plus monthly_fee. Required on installment_plan, greater than $0, at least monthly_fee, and no more than $1,000,000,000. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"promo_expires_month":{"default":null,"description":"Month at which apr_pct flips to revert_apr_pct, 1 to 480. Required on balance_transfer and promotional. Ignored on purchase, cash_advance and installment_plan.","type":["integer","null"]},"remaining_payments":{"default":null,"description":"Payments left in an installment plan's stated term, 0 or more. Optional on installment_plan, ignored on every other type. 0 means the term has ALREADY ended and is valid with any balance, including a positive residual. From 1 up, the balance must be clearable within the stated term and must not be clearable a month early.","type":["integer","null"]},"revert_apr_pct":{"default":null,"description":"Rate this segment reverts to once its promo expires, 0 to 100, and at least apr_pct. Required on balance_transfer and promotional. Ignored on purchase and cash_advance. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate rather than repricing.","type":["number","null"]},"stop_spend_month":{"default":null,"description":"Month index at which recurring spend stops, 0 or more. Read on purchase only, and range checked on every type. Omit to spend for the whole projection.","type":["integer","null"]},"type":{"description":"Segment type. REQUIRED on every segment: omitting it is rejected. Per-type field matrix. Every field below is classified for every segment type: REQUIRED (omitting it is rejected), OPTIONAL (accepted either way and read), IGNORED (accepted and never read for this type, though a value can still fail the field's own range check), or REJECTED (supplying a disallowed value is an error; the field's own rule below says exactly which values are disallowed). Value rules are stated separately from applicability, because a field can be accepted on a type and still be restricted there. The validators are the authority; this matrix describes them.\n- type: REQUIRED on every type. Values: one of purchase, cash_advance, balance_transfer, promotional, installment_plan.\n- balance: REQUIRED on every type. Values: $0 to $1,000,000,000; above $50,000 returns a HIGH_CARD_BALANCE warning, not an error.\n- apr_pct: REQUIRED on purchase, cash_advance, balance_transfer, promotional; OPTIONAL on installment_plan. Values: 0 to 100 as a percentage, e.g. 24.99 not 0.2499. The REQUIRED classification above applies when balance is greater than 0; a zero-balance segment may omit it. Must be greater than 0 on cash_advance carrying a balance. Must equal 0 on installment_plan, where omitting it is the correct shape.\n- revert_apr_pct: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance; REJECTED on installment_plan. Values: 0 to 100, and at least apr_pct. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate.\n- promo_expires_month: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance, installment_plan. Values: 1 to 480.\n- monthly_fee: OPTIONAL on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: $0 or more, and no greater than plan_payment_due, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- plan_payment_due: REQUIRED on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: greater than $0, at least monthly_fee, and no more than $1,000,000,000, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- remaining_payments: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 0 or more. 0 means the stated term has ALREADY ended and is valid with any balance. From 1 up, balance must be clearable within the stated term.\n- min_payment_order: OPTIONAL on every type. Values: 1 or more; breaks a tie only between segments sharing both the same current APR and the same installment-plan status.\n- extra_payment_order: OPTIONAL on every type. Values: 0 or more; 0 means skip. Breaks a tie only between segments sharing the exact same current APR.\n- merchant_name: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 120 characters or fewer.\n- monthly_spend: OPTIONAL on purchase; REJECTED on cash_advance, balance_transfer, promotional, installment_plan. Values: $0 to $50,000 per month. A negative value is rejected as NEGATIVE_BALANCE on every type, purchase included. On every type other than purchase a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; an explicit 0 is accepted.\n- stop_spend_month: OPTIONAL on purchase; IGNORED on cash_advance, balance_transfer, promotional, installment_plan. Values: 0 or more; range checked on every type, read only on purchase.","type":"string"}},"required":["type","balance"],"type":"object"},"type":["array","null"]},"stop_spend_month":{"description":"Month index at which this card's recurring spend stops, 0 or more. Optional; omit to spend for the whole projection.","type":["integer","null"]}},"type":"object"},"maxItems":20,"type":"array"},"chart_title":{"default":null,"description":"Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.","maxLength":120,"type":["string","null"]},"extra_monthly_payment":{"default":null,"description":"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums. Optional; defaults to 0 when omitted.","type":["number","null"]},"fixed_payments":{"default":null,"description":"Whether to hold each card's payment constant for the whole payoff. Optional; defaults to false when omitted. When true, each card's payment is locked at max(cards[].minimum_payment, that card's issuer minimum computed at month 1), and the total monthly budget (those locked amounts plus extra_monthly_payment) is held constant for the whole payoff, so once a card is paid off its freed-up payment rolls forward onto the remaining cards. This is the ONLY mode in which cards[].minimum_payment affects calculate_cc_payoff's result; compare_payoff_strategies has no fixed_payments parameter and binds minimum_payment on both of its strategy arms regardless.","type":["boolean","null"]},"full_schedule":{"default":null,"description":"Whether to return the full per-card month-by-month schedule. Optional; defaults to false when omitted. The per-card monthly_schedule is capped at 1000 rows total across cards and months, so later months are omitted on a long multi-card payoff; the portfolio-level monthly_totals series is always complete and is the one to read for the whole timeline.","type":["boolean","null"]},"include_card_timeline":{"default":null,"description":"Whether to add the card_timeline block, a per-card view of when each card clears. Optional; defaults to false when omitted.","type":["boolean","null"]},"output":{"description":"Valid values: 'summary' (default), 'inline'. summary returns a compact response with a data_preview block; inline returns the full payload.","enum":["summary","inline",null],"type":["string","null"]},"per_segment":{"default":null,"description":"Whether each schedule row carries its per-segment breakdown. Optional; defaults to true when omitted.","type":["boolean","null"]},"strategy":{"default":null,"description":"Payoff order: 'avalanche' pays the highest APR first, 'snowball' the smallest balance first. Optional; defaults to 'avalanche' when omitted. Matched case-insensitively, and the response echoes the canonical lowercase form actually simulated.","enum":["avalanche","snowball",null],"type":["string","null"]},"windfalls":{"default":null,"description":"One-time principal payments, at most 12, e.g. a tax refund or a year-end bonus. Optional; a JSON null is treated as omitted. When non-empty the response gains baseline, with_windfalls, months_saved_vs_baseline, interest_saved_vs_baseline, windfalls_applied[] and windfalls_unused[]; an empty array returns the same shape as omitting it.","items":{"properties":{"amount":{"description":"Dollar amount of the windfall, greater than 0. Required per entry.","type":["number","null"]},"label":{"description":"Optional label for this windfall, e.g. 'Tax refund' or 'Year-end bonus'. Max 120 characters.","maxLength":120,"type":["string","null"]},"month":{"description":"Month index the windfall is applied, 0 or more. 0 means applied before month 1's interest; N >= 1 applies at the end of calendar month N. Required per entry.","type":["integer","null"]}},"type":["object","null"]},"maxItems":12,"type":["array","null"]}},"required":["cards"],"type":"object"}⟨61 unchanged words⟩ keeping the current credit cards, and pick`rent_vs_buy``compare_rent_vs_buy` when the question is whether to buy a ⟨196 unchanged words⟩
before
{"properties":{"additional_income":{"default":null,"description":"Additional monthly income: side income, rental income, or bonuses. Optional; defaults to 0 when omitted. Must be zero or more.","type":["number","null"]},"annual_income":{"default":null,"description":"Annual gross income in dollars, divided by 12 to get monthly income. Exactly one of gross_monthly_income or annual_income is required. Must be at least $0.01, one cent, the smallest amount of money.","type":["number","null"]},"existing_debts":{"default":null,"description":"Existing debts to include in the DTI calculation. Optional; omit it or send an empty array for no existing debts. A JSON null is rejected; omit the field instead. At most 50 debts are allowed.","items":{"properties":{"apr_pct":{"description":"Annual percentage rate, as a percentage (0-100), e.g. 18.5 for 18.5%. Optional.","type":["number","null"]},"balance":{"description":"Current balance in dollars. Optional; used for payoff cost analysis in what-if scenarios.","type":["number","null"]},"monthly_payment":{"description":"Monthly payment in dollars. Required per debt; must be positive.","type":["number","null"]},"months_remaining":{"description":"Months remaining on this debt. Optional; used for the 10-month rule exclusion.","type":["integer","null"]},"name":{"description":"Optional label for this debt, e.g. 'Car Loan'.","type":["string","null"]},"type":{"description":"Debt type: 'auto', 'student', 'credit_card', 'personal', 'mortgage', 'heloc', 'child_support', or 'other'. Optional, defaults to 'other' when omitted; an unrecognized value warns rather than rejects.","type":["string","null"]}},"type":["object","null"]},"type":["array","null"]},"family_size":{"default":null,"description":"Household size for the VA residual income guideline. Supply family_size and property_state together, or neither. Optional; must be between 1 and 20.","type":["integer","null"]},"gross_monthly_income":{"default":null,"description":"Gross monthly income in dollars. Exactly one of gross_monthly_income or annual_income is required. Must be at least $0.01, one cent, the smallest amount of money.","type":["number","null"]},"hoa_monthly":{"default":null,"description":"Monthly homeowners association dues in dollars. Optional; defaults to 0 when omitted. Must be zero or more.","type":["number","null"]},"home_insurance_annual":{"default":null,"description":"Annual home insurance in dollars. Optional; if omitted, estimated at 0.65% of the proposed home price. Must be zero or more.","type":["number","null"]},"include_what_if":{"default":null,"description":"Whether to generate what-if scenarios showing how paying off a debt, increasing income, or reducing the home price would improve DTI. Optional; defaults to true when omitted.","type":["boolean","null"]},"monthly_maintenance_and_utilities":{"default":null,"description":"Estimated monthly maintenance and utilities for the proposed property. 38 CFR 36.4340 calls for a realistic estimate of this figure for the property and local utility rates and sets no numeric multiplier itself, but VA underwriting guidance (the Lender's Handbook, Pamphlet 26-7) publishes a per-square-foot multiplier for this same estimate. Applying it needs the property's square footage, which this tool does not currently collect, so Senaro has no default to offer here and you supply the aggregate monthly amount instead. Supplying BOTH this field and monthly_taxes_and_retirement_withholding, together with proposed_home_price and a computable family_size/property_state, computes qualification.va.residual_income_comparison: your ACTUAL monthly residual income, its ratio to the va_residual_income_guideline figure, and whether residual_income_meets_review_waiver_margin (residual income at or above 120% of the guideline) is met. The shelter expense used here excludes any PMI (VA loans carry no monthly PMI; 38 CFR 36.4313(e) sets a funding fee instead, commonly financed into the loan; see va_funding_fee_financed_monthly for the financed-fee field). 38 CFR 36.4340(c)(3)'s review-waiver condition is CONJUNCTIVE: it also requires the back-end debt-to-income ratio (qualification.va.your_back_end) to exceed 41%, which this field does not by itself confirm. Check both fields together. Even when both hold, (c)(3) only WAIVES a second-level review requirement; it is not itself an approval. Whether this file is actually approved is an underwriting determination Senaro does not make and no input combination here determines. Missing any one of the needed inputs reads qualification.va.residual_income_comparison.status 'not_computable' with every reason named. Optional; must be zero or more.","type":["number","null"]},"monthly_taxes_and_retirement_withholding":{"default":null,"description":"Your federal, state, and FICA tax withholding, plus any amount paid or withheld for retirement, monthly. 38 CFR 36.4340(f)(13) treats these as one class of deduction from gross income. Optional; must be zero or more.","type":["number","null"]},"pmi_monthly":{"default":null,"description":"Monthly PMI (private mortgage insurance) in dollars. Optional; if omitted, auto-estimated at 0.5% of the loan annually when loan-to-value exceeds 80%. Feeds the conventional-basis PITI, so it moves with_proposed.front_end_dti, with_proposed.back_end_dti, with_proposed.front_end_breakdown, the conventional qualification row, and what_if.scenarios[].new_front_end_dti and new_back_end_dti. VA carries no PMI, and FHA and USDA always compute their own upfront-plus-annual mortgage insurance instead, at every loan-to-value, never this override. Must be zero or more.","type":["number","null"]},"property_state":{"default":null,"description":"Two-letter USPS state code, or 'DC'/'PR'/'GU'/'VI'/'AS'/'MP'. Supply family_size and property_state together, or neither. Together these compute the VA residual income guideline (38 CFR 36.4340(e)) in va_residual_income_guideline: the dollar amount VA's tables require for this family size, region, and loan amount (derived from proposed_home_price; not computable without it), plus the 38 CFR 36.4340(c)(3) review-waiver figure. Computed only for family_size 1-7 and a property_state among the 50 states, DC, or PR (not GU, VI, AS, or MP; 38 CFR 36.4340(e) assigns no region to those four); outside those bounds, or without proposed_home_price, va_residual_income_guideline.status reads 'not_computable' with the reason instead. This block alone is a LOOKUP, not a verdict: it never compares against your actual residual income by itself. Optional.","type":["string","null"]},"property_tax_annual":{"default":null,"description":"Annual property tax in dollars. Optional; if omitted, estimated at 0.88% of the proposed home price. Must be zero or more.","type":["number","null"]},"proposed_debt":{"default":null,"description":"A proposed new debt, as an alternative to proposed_home_price. Provide at most one of proposed_debt or proposed_home_price; providing neither computes the current DTI only. Optional; a JSON null is treated as omitted, the same as leaving the field out.","properties":{"includes_tax_insurance":{"description":"Whether monthly_payment already includes tax and insurance. Optional, defaults to true when omitted; if false and type is 'mortgage', warns that lenders use full PITI for DTI.","type":["boolean","null"]},"monthly_payment":{"description":"Monthly payment in dollars. Required; must be positive.","type":["number","null"]},"name":{"description":"Optional label for this proposed debt.","type":["string","null"]},"type":{"description":"Debt type: 'auto', 'student', 'credit_card', 'personal', 'mortgage', 'heloc', 'child_support', or 'other'. Optional, defaults to 'mortgage' when omitted; an unrecognized value is rejected.","type":["string","null"]}},"type":["object","null"]},"proposed_down_payment_pct":{"default":null,"description":"Down payment as a percent of the proposed home price, e.g. 20 for 20%. Optional; defaults to 20 when omitted. Must be between 0 and 99.9 (100% cash purchases are not supported).","type":["number","null"]},"proposed_home_price":{"default":null,"description":"Proposed home purchase price in dollars. Provide at most one of proposed_debt or proposed_home_price; providing neither computes the current DTI only. Auto-calculates full PITI (principal, interest, taxes, insurance). Optional; must be at least $0.01, one cent, the smallest amount of money.","type":["number","null"]},"proposed_rate_pct":{"default":null,"description":"Proposed mortgage interest rate as a percent, e.g. 7.0 for 7.0%. Optional; the 7.0% default applies whenever this field is omitted, whether the proposal is proposed_debt or proposed_home_price. The default-rate warning fires only when proposed_home_price is used. Must be between 0 and 20.","type":["number","null"]},"proposed_term_years":{"default":null,"description":"Proposed mortgage term in years. Optional; defaults to 30 when omitted. Must be between 1 and 40.","type":["integer","null"]},"transaction_purpose":{"default":null,"description":"Mortgage transaction purpose: 'purchase', 'refinance', or 'streamlined_assist'. Optional, defaults to 'purchase' when omitted. Affects USDA only, and only what is disclosed. USDA's 32% PITI and 44% Total Debt figures are purchase-transaction waiver conditions (HB-1-3555 11.3.A.2), disclosed rather than applied as ceilings: Senaro cannot observe how the file is underwritten, so a USDA ratio overage is never 'ineligible' on any transaction purpose. For a refinance, 11.3.B states debt ratios 'are not limited to the maximum purchase debt ratio thresholds', so where the note fires it names both figures and states that neither applies. Streamlined-assist refinances require no debt ratio calculation at all. Conventional, FHA and VA are unaffected.","type":["string","null"]},"va_funding_fee_financed_monthly":{"default":null,"description":"The additional monthly payment from financing a VA funding fee into the loan balance, if any. 38 CFR 36.4313(e)'s applicable percentage depends on down payment, prior VA-loan use, and service category, none of which Senaro collects, so there is no default. If omitted while any VA figure that depends on it is produced, meaning qualification.va.your_back_end and its verdict, any what_if VA ratio, what_if.max_affordable_home.va, or qualification.va.residual_income_comparison, a VA_FUNDING_FEE_NOT_MODELED warning discloses that no fee is assumed. The home-price-reduction what_if scenario's hypothetical price is fixed before the fee is considered, so a supplied fee is scaled to that EXACT hypothetical loan size, since 38 CFR 36.4313(e)'s fee is a percentage of loan principal. what_if.max_affordable_home.va is a two-pass approximation instead, so its supplied fee is scaled to an ESTIMATE of the hypothetical loan size, not the exact figure reported; the PMI, tax, and insurance reservation itself is an EXACT closed-form solve, so only this fee-scaling step is approximate. Without proposed_home_price there is no reference loan size to scale from either way, so the raw fee is reserved unscaled instead, and a VA_FUNDING_FEE_NOT_SCALED warning discloses it. This is mutually exclusive with VA_FUNDING_FEE_NOT_MODELED by construction, since one requires the fee omitted and the other requires it supplied. Optional; must be zero or more.","type":["number","null"]}},"type":"object"}after
{"properties":{"additional_income":{"default":null,"description":"Additional monthly income: side income, rental income, or bonuses. Optional; defaults to 0 when omitted. Must be zero or more.","type":["number","null"]},"annual_income":{"default":null,"description":"Annual gross income in dollars, divided by 12 to get monthly income. Exactly one of gross_monthly_income or annual_income is required. Must be at least $0.01, one cent, the smallest amount of money.","minimum":0.01,"type":["number","null"]},"existing_debts":{"default":null,"description":"Existing debts to include in the DTI calculation. Optional; omit it or send an empty array for no existing debts. A JSON null is rejected; omit the field instead. At most 50 debts are allowed.","items":{"properties":{"apr_pct":{"description":"Annual percentage rate, as a percentage (0-100), e.g. 18.5 for 18.5%. Optional.","type":["number","null"]},"balance":{"description":"Current balance in dollars. Optional; used for payoff cost analysis in what-if scenarios.","type":["number","null"]},"monthly_payment":{"description":"Monthly payment in dollars. Required per debt; must be positive.","type":["number","null"]},"months_remaining":{"description":"Months remaining on this debt. Optional; used for the 10-month rule exclusion.","type":["integer","null"]},"name":{"description":"Optional label for this debt, e.g. 'Car Loan'. At most 120 characters.","maxLength":120,"type":["string","null"]},"type":{"description":"Debt type: 'auto', 'student', 'credit_card', 'personal', 'mortgage', 'heloc', 'child_support', or 'other'. Optional, defaults to 'other' when omitted. An unrecognized value of at most 120 characters warns rather than rejects; a longer one is rejected.","maxLength":120,"type":["string","null"]}},"type":["object","null"]},"maxItems":50,"type":["array","null"]},"family_size":{"default":null,"description":"Household size for the VA residual income guideline. Supply family_size and property_state together, or neither. Optional; must be between 1 and 20.","maximum":20,"type":["integer","null"]},"gross_monthly_income":{"default":null,"description":"Gross monthly income in dollars. Exactly one of gross_monthly_income or annual_income is required. Must be at least $0.01, one cent, the smallest amount of money.","minimum":0.01,"type":["number","null"]},"hoa_monthly":{"default":null,"description":"Monthly homeowners association dues in dollars. Optional; defaults to 0 when omitted. Must be zero or more.","type":["number","null"]},"home_insurance_annual":{"default":null,"description":"Annual home insurance in dollars. Optional; if omitted, estimated at 0.65% of the proposed home price. Must be zero or more.","type":["number","null"]},"include_what_if":{"default":null,"description":"Whether to generate what-if scenarios showing how paying off a debt, increasing income, or reducing the home price would improve DTI. Optional; defaults to true when omitted.","type":["boolean","null"]},"monthly_maintenance_and_utilities":{"default":null,"description":"Estimated monthly maintenance and utilities for the proposed property. 38 CFR 36.4340 calls for a realistic estimate of this figure for the property and local utility rates and sets no numeric multiplier itself, but VA underwriting guidance (the Lender's Handbook, Pamphlet 26-7) publishes a per-square-foot multiplier for this same estimate. Applying it needs the property's square footage, which this tool does not currently collect, so Senaro has no default to offer here and you supply the aggregate monthly amount instead. Supplying BOTH this field and monthly_taxes_and_retirement_withholding, together with proposed_home_price and a computable family_size/property_state, computes qualification.va.residual_income_comparison: your ACTUAL monthly residual income, its ratio to the va_residual_income_guideline figure, and whether residual_income_meets_review_waiver_margin (residual income at or above 120% of the guideline) is met. The shelter expense used here excludes any PMI (VA loans carry no monthly PMI; 38 CFR 36.4313(e) sets a funding fee instead, commonly financed into the loan; see va_funding_fee_financed_monthly for the financed-fee field). 38 CFR 36.4340(c)(3)'s review-waiver condition is CONJUNCTIVE: it also requires the back-end debt-to-income ratio (qualification.va.your_back_end) to exceed 41%, which this field does not by itself confirm. Check both fields together. Even when both hold, (c)(3) only WAIVES a second-level review requirement; it is not itself an approval. Whether this file is actually approved is an underwriting determination Senaro does not make and no input combination here determines. Missing any one of the needed inputs reads qualification.va.residual_income_comparison.status 'not_computable' with every reason named. Optional; must be zero or more.","type":["number","null"]},"monthly_taxes_and_retirement_withholding":{"default":null,"description":"Your federal, state, and FICA tax withholding, plus any amount paid or withheld for retirement, monthly. 38 CFR 36.4340(f)(13) treats these as one class of deduction from gross income. Optional; must be zero or more.","type":["number","null"]},"pmi_monthly":{"default":null,"description":"Monthly PMI (private mortgage insurance) in dollars. Optional; if omitted, auto-estimated at 0.5% of the loan annually when loan-to-value exceeds 80%. Feeds the conventional-basis PITI, so it moves with_proposed.front_end_dti, with_proposed.back_end_dti, with_proposed.front_end_breakdown, the conventional qualification row, and what_if.scenarios[].new_front_end_dti and new_back_end_dti. VA carries no PMI, and FHA and USDA always compute their own upfront-plus-annual mortgage insurance instead, at every loan-to-value, never this override. Must be zero or more.","type":["number","null"]},"property_state":{"default":null,"description":"Two-letter USPS state code, or 'DC'/'PR'/'GU'/'VI'/'AS'/'MP'. Supply family_size and property_state together, or neither. Together these compute the VA residual income guideline (38 CFR 36.4340(e)) in va_residual_income_guideline: the dollar amount VA's tables require for this family size, region, and loan amount (derived from proposed_home_price; not computable without it), plus the 38 CFR 36.4340(c)(3) review-waiver figure. Computed only for family_size 1-7 and a property_state among the 50 states, DC, or PR (not GU, VI, AS, or MP; 38 CFR 36.4340(e) assigns no region to those four); outside those bounds, or without proposed_home_price, va_residual_income_guideline.status reads 'not_computable' with the reason instead. This block alone is a LOOKUP, not a verdict: it never compares against your actual residual income by itself. Optional.","type":["string","null"]},"property_tax_annual":{"default":null,"description":"Annual property tax in dollars. Optional; if omitted, estimated at 0.88% of the proposed home price. Must be zero or more.","type":["number","null"]},"proposed_debt":{"default":null,"description":"A proposed new debt, as an alternative to proposed_home_price. Provide at most one of proposed_debt or proposed_home_price; providing neither computes the current DTI only. Optional; a JSON null is treated as omitted, the same as leaving the field out.","properties":{"includes_tax_insurance":{"description":"Whether monthly_payment already includes tax and insurance. Optional, defaults to true when omitted; if false and type is 'mortgage', warns that lenders use full PITI for DTI.","type":["boolean","null"]},"monthly_payment":{"description":"Monthly payment in dollars. Required; must be positive.","type":["number","null"]},"name":{"description":"Optional label for this proposed debt. At most 120 characters.","maxLength":120,"type":["string","null"]},"type":{"description":"Debt type: 'auto', 'student', 'credit_card', 'personal', 'mortgage', 'heloc', 'child_support', or 'other'. Optional, defaults to 'mortgage' when omitted; an unrecognized value is rejected.","enum":["credit_card","auto","student","personal","mortgage","heloc","child_support","other",null],"type":["string","null"]}},"type":["object","null"]},"proposed_down_payment_pct":{"default":null,"description":"Down payment as a percent of the proposed home price, e.g. 20 for 20%. Optional; defaults to 20 when omitted. Must be between 0 and 99.9 (100% cash purchases are not supported).","type":["number","null"]},"proposed_home_price":{"default":null,"description":"Proposed home purchase price in dollars. Provide at most one of proposed_debt or proposed_home_price; providing neither computes the current DTI only. Auto-calculates full PITI (principal, interest, taxes, insurance). Optional; must be at least $0.01, one cent, the smallest amount of money.","minimum":0.01,"type":["number","null"]},"proposed_rate_pct":{"default":null,"description":"Proposed mortgage interest rate as a percent, e.g. 7.0 for 7.0%. Optional; the 7.0% default applies whenever this field is omitted, whether the proposal is proposed_debt or proposed_home_price. The default-rate warning fires only when proposed_home_price is used. Must be between 0 and 20.","type":["number","null"]},"proposed_term_years":{"default":null,"description":"Proposed mortgage term in years. Optional; defaults to 30 when omitted. Must be between 1 and 40.","type":["integer","null"]},"transaction_purpose":{"default":null,"description":"Mortgage transaction purpose: 'purchase', 'refinance', or 'streamlined_assist'. Optional, defaults to 'purchase' when omitted. Affects USDA only, and only what is disclosed. USDA's 32% PITI and 44% Total Debt figures are purchase-transaction waiver conditions (HB-1-3555 11.3.A.2), disclosed rather than applied as ceilings: Senaro cannot observe how the file is underwritten, so a USDA ratio overage is never 'ineligible' on any transaction purpose. For a refinance, 11.3.B states debt ratios 'are not limited to the maximum purchase debt ratio thresholds', so where the note fires it names both figures and states that neither applies. Streamlined-assist refinances require no debt ratio calculation at all. Conventional, FHA and VA are unaffected.","enum":["purchase","refinance","streamlined_assist",null],"type":["string","null"]},"va_funding_fee_financed_monthly":{"default":null,"description":"The additional monthly payment from financing a VA funding fee into the loan balance, if any. 38 CFR 36.4313(e)'s applicable percentage depends on down payment, prior VA-loan use, and service category, none of which Senaro collects, so there is no default. If omitted while any VA figure that depends on it is produced, meaning qualification.va.your_back_end and its verdict, any what_if VA ratio, what_if.max_affordable_home.va, or qualification.va.residual_income_comparison, a VA_FUNDING_FEE_NOT_MODELED warning discloses that no fee is assumed. The home-price-reduction what_if scenario's hypothetical price is fixed before the fee is considered, so a supplied fee is scaled to that EXACT hypothetical loan size, since 38 CFR 36.4313(e)'s fee is a percentage of loan principal. what_if.max_affordable_home.va is a two-pass approximation instead, so its supplied fee is scaled to an ESTIMATE of the hypothetical loan size, not the exact figure reported; the PMI, tax, and insurance reservation itself is an EXACT closed-form solve, so only this fee-scaling step is approximate. Without proposed_home_price there is no reference loan size to scale from either way, so the raw fee is reserved unscaled instead, and a VA_FUNDING_FEE_NOT_SCALED warning discloses it. This is mutually exclusive with VA_FUNDING_FEE_NOT_MODELED by construction, since one requires the fee omitted and the other requires it supplied. Optional; must be zero or more.","type":["number","null"]}},"type":"object"}⟨13 unchanged words⟩ em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"current_savings ⟨128 unchanged words⟩ . Optional; defaults to 'stable_w2' when omitted.","enum":["stable_w2","variable_income","self_employed","between_jobs",null],"type":["string","null"]},"monthly_essential_expenses ⟨19 unchanged words⟩ $1,000,000,000. REQUIRED, no default.","minimum":0.01,"type":"number"},"monthly_savings_capacity":{" ⟨38 unchanged words⟩
⟨48 unchanged words⟩ quarterly; <=360: yearly; else biennial).","enum":["auto","monthly","quarterly","yearly","biennial",null],"type":["string","null"]},"chart_title ⟨11 unchanged words⟩ em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"extra_monthly_payment ⟨33 unchanged words⟩ 'mortgage'. Optional; defaults to 'personal' when omitted.","enum":["personal","auto","student","mortgage",null],"type":["string","null"]},"output ⟨12 unchanged words⟩ analysis.buckets[] inline.","enum":["summary",null],"type":["string","null"]},"principal":{"description":"Loan principal ⟨15 unchanged words⟩ Integer, greater than 0. REQUIRED, no default.","maximum":480,"type":"integer"}},"required":[ ⟨5 unchanged words⟩
⟨27 unchanged words⟩ this when the input is recurring spending. Pick`compound_interest``calculate_compound_interest` when the input is a balance and its contributions with no spending to price, and`payoff_vs_invest``compare_payoff_vs_invest` when the alternative to investing is paying down ⟨22 unchanged words⟩
⟨42 unchanged words⟩ em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"label ⟨5 unchanged words⟩ spending is, e.g. 'coffee' or 'streaming subscriptions'. Optional. Max 120 characters.","maxLength":120,"type":["string","null"]},"monthly_spending ⟨18 unchanged words⟩ degenerate and is rejected. REQUIRED, no default.","minimum":0.01,"type":"number"},"tax_bracket_pct":{" ⟨47 unchanged words⟩
⟨47 unchanged words⟩ it hits zero, plus a month-by-month drawdown schedule.Single scenario per call: to compare 'status quo' ⟨8 unchanged words⟩ per scenario with the matching expenses and inflows.When inflows meet or exceed expenses (and expenses ⟨12 unchanged words⟩ does-not-deplete outcome is returned instead of a month.Yield on the fund is treated as 0% in v1 (conservative). All assumptions cite their source.Pick this to project how many months current ⟨14 unchanged words⟩ fund's target size, not how long it lasts.HEAVY tool: use output='summary' (default) for the ⟨7 unchanged words⟩
⟨66 unchanged words⟩ em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"current_savings ⟨140 unchanged words⟩ rendering.","enum":["summary","inline",null],"type":["string","null"]},"use_essential_expenses":{"default":null,"description" ⟨33 unchanged words⟩
⟨22 unchanged words⟩ or head-to-head multi-offer comparison via bt_offers[]).Supports partial balance transfers via bt_transfer_limit: transfers only ⟨27 unchanged words⟩ together, so freed minimum payments are correctly redistributed.Shows total cost, interest saved, monthly payment ⟨14 unchanged words⟩ Works with multiple cards including cash advance balances.Pick this to weigh a consolidation loan (required ⟨15 unchanged words⟩ timeline with no consolidation option, and pick`compare_strategies``compare_payoff_strategies` to compare avalanche against snowball ordering on the cards as they stand.The response includes `chart_hints` with rendering directives any ⟨5 unchanged words⟩ MCP server renders them locally over stdio only.HEAVY tool: use output='summary' (default) for the ⟨8 unchanged words⟩
before
{"properties":{"bt_apr_pct":{"default":null,"description":"Balance-transfer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required when include_balance_transfer is true and bt_offers is omitted. bt_offers, when supplied, overrides this and the other three bt_* scalars below. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_fee_pct":{"default":null,"description":"Balance-transfer fee as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted. bt_offers, when supplied, overrides this. The 0-10 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_manual_transfers":{"default":null,"description":"Exact per-card transfer amounts. Required when bt_transfer_strategy is 'manual'; each entry's card_name must match a name in cards[]. Optional otherwise; a JSON null is treated as omitted, the same as leaving the field out.","items":{"properties":{"amount":{"description":"Dollar amount to transfer from this card, greater than $0, up to $1,000,000,000. Required per entry.","type":["number","null"]},"card_name":{"description":"Card name; must match a name in cards[]. Required per entry. Max 120 characters.","type":["string","null"]}},"type":["object","null"]},"type":["array","null"]},"bt_offers":{"default":null,"description":"Balance-transfer offers to compare head-to-head, 1 to 10, preferred over the four scalar bt_* fields above when comparing two or more offers: when supplied, bt_offers overrides bt_apr_pct, bt_promo_months, bt_regular_apr_pct, and bt_fee_pct, and their range checks are skipped. The response includes a balance_transfer_offers block with per-offer simulation results, selected_offer_index, selected_offer_label, selected_offer_reason, and all_offers_trap. Optional; a JSON null is rejected, unlike bt_manual_transfers and windfalls below, where a JSON null is treated as omitted.","items":{"properties":{"apr_pct":{"description":"Offer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required per offer.","type":["number","null"]},"fee_pct":{"description":"Balance-transfer fee for this offer, as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted.","type":["number","null"]},"label":{"description":"Label for this offer. Optional; defaults to '<apr_pct>% / <promo_months>mo' when omitted. Max 120 characters.","type":["string","null"]},"promo_months":{"description":"This offer's promo period in months, 1-60. Optional; defaults to 18 when omitted.","type":["integer","null"]},"regular_apr_pct":{"description":"APR that applies after this offer's promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted.","type":["number","null"]}},"type":["object","null"]},"type":["array","null"]},"bt_promo_months":{"default":null,"description":"Balance-transfer promo period in months, 1-60. Optional; defaults to 18 when omitted. bt_offers, when supplied, overrides this. The 1-60 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["integer","null"]},"bt_regular_apr_pct":{"default":null,"description":"APR that applies after the promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted. bt_offers, when supplied, overrides this. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_transfer_limit":{"default":null,"description":"Cap on the total dollar amount transferred to the balance-transfer card, at least $0.01. When set, only this amount moves to the BT card; remaining balances stay on original cards, and a combined simulation runs both halves together, correctly redistributing freed minimum payments. Optional; when omitted, the entire balance is transferred (legacy behavior). Needs include_balance_transfer or bt_offers.","type":["number","null"]},"bt_transfer_strategy":{"default":null,"description":"How to choose which balances move when bt_transfer_limit is less than your total debt: 'highest_apr_first' (transfer from highest-APR segments first, maximizes interest savings), 'highest_balance_first' (transfer largest balances first), or 'manual' (use bt_manual_transfers to specify exact amounts per card). Optional; defaults to 'highest_apr_first' when omitted. Needs bt_transfer_limit.","type":["string","null"]},"cards":{"description":"Credit cards to include, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards must be a JSON array.\"); the two are not the same rejection. segments and stop_spend_month are not supported by this tool and are rejected; a non-zero monthly_spend, annual_fee, or plan_fees_monthly is rejected too, but zero (including an explicit 0) is accepted and dropped for all three: this tool always reads the flat purchase_balance / cash_advance_balance fields on each card below, never segments[] balances, and card-level fees and ongoing spend are not modeled here. Those five fields are supported by calculate_cc_payoff and compare_strategies instead.","items":{"properties":{"cash_advance_apr_pct":{"description":"Cash advance APR as a percentage, greater than 0, up to 100. Required when cash_advance_balance is greater than 0.","type":["number","null"]},"cash_advance_balance":{"description":"Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted.","type":["number","null"]},"minimum_payment":{"description":"Minimum payment in dollars, $0 to $1,000,000,000. Optional; 0 or omitted auto-calculates the bank minimum. Used as the locked floor for the constant keep-cards payment: each card pays max(your minimum, the bank minimum), held constant and rolled forward as cards clear.","type":["number","null"]},"name":{"description":"Card label, e.g. 'Chase Sapphire'. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', ...). Max 120 characters.","type":["string","null"]},"purchase_apr_pct":{"description":"Purchase APR as a percentage, 0-100, e.g. 22.99. Required per card.","type":["number","null"]},"purchase_balance":{"description":"Purchase balance in dollars, $0 to $1,000,000,000. Required per card.","type":["number","null"]}},"type":"object"},"type":"array"},"chart_title":{"default":null,"description":"Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.","type":["string","null"]},"consolidation_loan":{"description":"Loan terms for the consolidation option. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"consolidation_loan must be an object.\"); the two are not the same rejection.","properties":{"annual_rate_pct":{"description":"Annual interest rate for the consolidation loan, as a percentage, 0-36, e.g. 10.99. Required.","type":["number","null"]},"include_fee_in_principal":{"description":"Whether the origination fee is rolled into the loan principal rather than paid upfront. Optional; defaults to true when omitted. A JSON null is rejected; omit the field instead of sending null.","type":["boolean","null"]},"origination_fee_flat":{"description":"Flat-dollar origination fee, $0 to $10,000. Optional; defaults to 0 when omitted, and takes precedence over origination_fee_pct when it produces a larger fee. A JSON null is rejected; omit the field instead of sending null.","type":["number","null"]},"origination_fee_pct":{"description":"Origination fee as a percentage of loan principal, 0-10. Optional; defaults to 0 when omitted. A JSON null is rejected, unlike every other optional field on this tool; omit the field instead of sending null.","type":["number","null"]},"term_months":{"description":"Consolidation loan term in months, 12-84. Required.","type":["integer","null"]}},"type":"object"},"current_strategy":{"default":null,"description":"Your current payoff strategy, compared against the consolidation loan / balance-transfer alternative: 'avalanche' or 'snowball'. Optional; defaults to 'avalanche' when omitted. Case-sensitive.","type":["string","null"]},"extra_monthly_payment":{"default":null,"description":"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums for keep-cards and any balance transfer, and on top of the loan's own required payment for consolidation. Optional; defaults to 0 when omitted. fixed_payments is not a parameter of this tool, unlike calculate_cc_payoff: the keep-cards baseline is always simulated under the canonical constant rolled-forward payment (see comparison_basis in the response); supplying fixed_payments returns an unknown_parameter error.","type":["number","null"]},"full_schedule":{"default":null,"description":"Whether to return the full month-by-month amortization schedule instead of the compact default. Optional; defaults to false when omitted.","type":["boolean","null"]},"include_balance_transfer":{"default":null,"description":"Whether to run a single-offer balance-transfer scenario using the four scalar bt_* fields below. Optional; defaults to false when omitted. Ignored once bt_offers is supplied; use bt_offers when comparing two or more offers.","type":["boolean","null"]},"output":{"description":"Valid values: 'summary' (default), 'inline'. summary: compact response with a data_preview block; no heavy array exists on this response today, so summary and inline are currently identical in content. inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering).","enum":["summary","inline"],"type":"string"},"windfalls":{"default":null,"description":"One-time principal payments, at most 12, same shape as calculate_cc_payoff. Optional; a JSON null is treated as omitted, the same as leaving the field out. When non-empty, the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples, except what_if.same_budget_accelerated, a windfall-free hypothetical about extra-payment behavior, not your actual lump-sum schedule.","items":{"properties":{"amount":{"description":"Dollar amount of the windfall, greater than 0. Required per entry.","type":["number","null"]},"label":{"description":"Optional label for this windfall, e.g. 'Tax refund' or 'Year-end bonus'. Max 120 characters.","type":["string","null"]},"month":{"description":"Month index the windfall is applied, 0 or more. 0 means applied before month 1's interest; N >= 1 applies at the end of calendar month N. Required per entry.","type":["integer","null"]}},"type":["object","null"]},"type":["array","null"]}},"required":["cards","consolidation_loan"],"type":"object"}⟨7 unchanged words⟩ before acting. Compare two fixed-rate mortgage options side-by-side: - 15 vs 30 year, - different rates, - points vs no points, or - any two terms.Shows total interest, monthly payment breakdown (with ⟨19 unchanged words⟩ monthly savings. Finds the break-even investment return rate.Includes tax deduction analysis (itemizing vs standard deduction ⟨5 unchanged words⟩ Homeowners Protection Act, and after-tax net worth comparison.Pick this to compare two mortgage structures on ⟨6 unchanged words⟩ 30 year or points versus no points; pick`refi_breakeven``calculate_refi_breakeven` when the comparison is against your existing loan and a refinance offer, and pick`compare_strategies``compare_payoff_strategies` when the question is payoff strategy on revolving debt, not a mortgage term.Note: ARM (adjustable-rate) mortgages are not yet supported.
⟨171 unchanged words⟩ 'married', or 'head_of_household'. Optional; matched case-insensitively.","enum":["single","married","head_of_household",null],"type":["string","null"]},"full_schedule ⟨302 unchanged words⟩ auto-generated when omitted. At most 120 characters.","maxLength":120,"type":["string","null"]},"points ⟨142 unchanged words⟩ auto-generated when omitted. At most 120 characters.","maxLength":120,"type":["string","null"]},"points ⟨359 unchanged words⟩ savings to its investments at year end.","maximum":50,"minimum":0,"type":["number","null"]},"tax_year ⟨15 unchanged words⟩ itemize-vs-standard analysis. Optional; defaults to 2026 when omitted.","maximum":2026,"minimum":2025,"type":["integer","null"]}, ⟨33 unchanged words⟩
⟨42 unchanged words⟩ returns inline JSON. JSON parameters (all optional):- category: string. Filter entries by category: the ⟨27 unchanged words⟩ . Case-insensitive. The 14 valid values: calculate_cc_payoff,calculate_debt_to_incomecalculate_compound_interest,calculate_emergency_fundcalculate_debt_to_income, calculate_emergency_fund, calculate_opportunity_cost, calculate_refi_breakeven, calculate_runway, compare_debt_consolidation, compare_mortgage_terms,compare_strategies,compound_interestcompare_payoff_strategies,optimize_401k_matchcompare_payoff_vs_invest,payoff_vs_investcompare_rent_vs_buy,refi_breakeven, rent_vs_buyoptimize_401k_match, shared. An unrecognized value returns validation_error listing the accepted set.- name: string. Return one full entry. Requires category. Returns validation_error if not found.- verbose: boolean. Return all 10 citation fields per ⟨42 unchanged words⟩
⟨10 unchanged words⟩ the canonical MCP tool name (e.g. \"rent_vs_buy\compare_rent_vs_buy\") or \"shared\". Case-insensitive.","type ⟨41 unchanged words⟩
⟨31 unchanged words⟩ preset or a custom tier list), computes: - the annual match you receive today; - the maximum match available (full match entitlement); - the match forfeited at your current rate; - the minimum contribution percent to receive the full match; - whether front-loading contributions would forfeit match at a no-true-up plan; and - a per-period schedule showing level vs. front-load paths side by side.Pick this to size 401(k) contributions against the employer match formula; pick`payoff_vs_invest``compare_payoff_vs_invest` when the question is putting an extra monthly ⟨13 unchanged words⟩ not how much of the match to receive.IRS limits (402(g) elective deferral, 401 ⟨51 unchanged words⟩ ceiling, not the bare 402(g) amount.HEAVY tool: use output='summary' (default) for the ⟨9 unchanged words⟩
⟨31 unchanged words⟩ em-dashes or en-dashes. Max 120 characters. Optional.","maxLength":120,"type":["string","null"]},"contribution_pct ⟨12 unchanged words⟩ 0, 100]. REQUIRED, no default.","maximum":100,"minimum":0,"type":"number"},"has_true_up":{"default" ⟨71 unchanged words⟩ is required. Optional; omit when supplying match_tiers.","enum":["safe_harbor_basic","safe_harbor_enhanced_simple","qaca","fifty_pct_of_first_six_pct",null],"type":["string","null"]},"match_tiers ⟨85 unchanged words⟩ "type":["object","null"]},"maxItems":10,"type":["array","null"]},"output ⟨18 unchanged words⟩ ].","enum":["summary","inline",null],"type":["string","null"]},"participant_age":{"default":null,"description" ⟨45 unchanged words⟩ [1, 365]. REQUIRED, no default.","maximum":365,"minimum":1,"type":"integer"}},"required":[ ⟨5 unchanged words⟩
Compound Interest Calculator — Calculation, not advice. Verify with a professional before acting. Standard compound interest calculator. Returns future value, total contributions, interest earned, effective annual rate, and milestones. Pick this for a balance that grows with contributions. Pick `calculate_opportunity_cost` when the money is recurring spending being priced against investing, and `calculate_loan_payoff` when the balance amortizes down under a fixed payment. The response includes `chart_hints` with rendering directives any client can use. The `senaro-charts` MCP server renders them locally over stdio only.
Refinance Break-Even Analysis — Calculation, not advice. Verify with a professional before acting. Deterministic mortgage refinance break-even analysis. Given your current loan (balance, rate, remaining term) and a refinance offer (new rate, new term, closing costs, optional points), computes: - monthly P&I savings; - the cash-flow break-even month (total refinance cost divided by monthly savings, CFPB convention); - the lifetime interest delta over your remaining-term horizon; - a term-matched scenario that isolates the rate cut from a term reset; - a term-reset-trap flag (lower payment but higher lifetime interest from e…
Payoff Strategy Comparison — Calculation, not advice. Verify with a professional before acting. Compare avalanche and snowball payoff strategies side-by-side. Pick this to compare avalanche against snowball ordering on the same set of cards; pick `calculate_cc_payoff` once a strategy is chosen and the need is a single payoff timeline with windfalls or fixed payments. Returns months, total interest, payoff order, savings, total_balance, weighted_average_apr_pct, monthly_interest_now, and cost_breakdown array. When an arm is not projected to reach a zero balance, the savings.* fields for that arm carry status: "none" with…
Debt Payoff vs. Invest — Calculation, not advice. Verify with a professional before acting. Compares the guaranteed return of debt payoff against expected investment returns over a time horizon. Accounts for post-payoff investing, tax implications, and finds the break-even investment return rate. Works for credit cards, auto loans, student loans, personal loans, and mortgages. Pick this when the alternative to investing is paying down an existing debt balance; pick `calculate_opportunity_cost` when there is no debt in the picture and the alternative is simply forgoing recurring spending to invest it instead. The r…
Rent vs. Buy Calculator — Calculation, not advice. Verify with a professional before acting. Deterministic rent-vs-buy decision model. Given a home price, monthly rent, and mortgage rate, computes the breakeven month (when BUY net worth first equals or exceeds RENT net worth), per-horizon net-worth comparison (years 5, 10, 30 + user horizon), and the full year-by-year cost/wealth series for both paths. Includes carrying costs (property tax, insurance, maintenance, PMI, HOA) on the BUY path and opportunity-cost investing on the RENT path. Optional federal tax benefit model (Tier-3: apply_tax_benefit=true) with TY2025…
Payoff Strategy Comparison — Calculation, not advice. Verify with a professional before acting. Compare avalanche and snowball payoff strategies side-by-side. Pick this to compare avalanche against snowball ordering on the same set of cards; pick `calculate_cc_payoff` once a strategy is chosen and the need is a single payoff timeline with windfalls or fixed payments. Returns months, total interest, payoff order, savings, total_balance, weighted_average_apr_pct, monthly_interest_now, and cost_breakdown array. When an arm is not projected to reach a zero balance, the savings.* fields for that arm carry status: "none" with …
Compound Interest Calculator — Calculation, not advice. Verify with a professional before acting. Standard compound interest calculator. Returns future value, total contributions, interest earned, effective annual rate, and milestones. Pick this for a balance that grows with contributions. Pick `calculate_opportunity_cost` when the money is recurring spending being priced against investing, and `calculate_loan_payoff` when the balance amortizes down under a fixed payment. The response includes `chart_hints` with rendering directives any client can use. The `senaro-charts` MCP server renders them locally over stdio only.
Debt Payoff vs. Invest — Calculation, not advice. Verify with a professional before acting. Compares the guaranteed return of debt payoff against expected investment returns over a time horizon. Accounts for post-payoff investing, tax implications, and finds the break-even investment return rate. Works for credit cards, auto loans, student loans, personal loans, and mortgages. Pick this when the alternative to investing is paying down an existing debt balance; pick `calculate_opportunity_cost` when there is no debt in the picture and the alternative is simply forgoing recurring spending to invest it instead. The resp…
Refinance Break-Even Analysis — Calculation, not advice. Verify with a professional before acting. Deterministic mortgage refinance break-even analysis. Given your current loan (balance, rate, remaining term) and a refinance offer (new rate, new term, closing costs, optional points), computes: monthly P&I savings; the cash-flow break-even month (total refinance cost divided by monthly savings, CFPB convention); the lifetime interest delta over your remaining-term horizon; a term-matched scenario that isolates the rate cut from a term reset; a term-reset-trap flag (lower payment but higher lifetime interest from extending th…
Rent vs. Buy Calculator — Calculation, not advice. Verify with a professional before acting. Deterministic rent-vs-buy decision model. Given a home price, monthly rent, and mortgage rate, computes the breakeven month (when BUY net worth first equals or exceeds RENT net worth), per-horizon net-worth comparison (years 5, 10, 30 + user horizon), and the full year-by-year cost/wealth series for both paths. Includes carrying costs (property tax, insurance, maintenance, PMI, HOA) on the BUY path and opportunity-cost investing on the RENT path. Optional federal tax benefit model (Tier-3: apply_tax_benefit=true) with TY2025/T…
⟨40 unchanged words⟩ refund, bonus, inheritance) applied at specific months.Returns: - debt-free date, total interest, per-card payoff order,- first_month_interest_ratio_frac (the first month's interest/payment fraction) and lifetime_interest_ratio_frac (whole-projection total_interest/total_paid fraction),- domain warnings emitted as warnings[].type (DEATH_SPIRAL ⟨3 unchanged words⟩ DEBT_GROWING, PROMO_CLIFF, PREDATORY_RATE, SPEND_EXCEEDS_PAYDOWN, PLAN_TERM_ELAPSED_WITH_BALANCE), and, separately, validation disclosures emitted as warnings[].code (MINIMUM_PAYMENT_NOT_BINDING ⟨20 unchanged words⟩ are distinguishable by which keys each entry carries), and- when a plan exists (extra_monthly_payment > 0, windfalls present, or fixed_payments = true), a min_payments_only baseline block with interest_saved_vs_min_payments and months_saved_vs_min_payments quantifying the interest and time difference versus paying minimumsonly.only;Whenwhen windfalls are also present the response additionally gains a baseline vs with_windfalls savingsblock.block The response echoes strategy (canonical lowercase 'avalanche' | ⟨5 unchanged words⟩ was actually simulated under) at the top level.The response includes `chart_hints` with rendering directives any ⟨5 unchanged words⟩ MCP server renders them locally over stdio only.output: 'capture' is available on the local stdio transport only, and is rejected with a structured error on the hosted HTTP transport, where a capture_ref would be a dead link for a remote caller; see the output parameter for the response verbosity modes.Top-level `entered_starting_balance` echoes the caller's supplied balances by ⟨46 unchanged words⟩ on every monthly_totals[] and analysis.buckets[] row.These month counts are each a {status, ⟨69 unchanged words⟩
⟨2069 unchanged words⟩ "boolean","null"]},"output":{"default":null,"description":"ResponseValidverbosityvalues: 'summary' (default)| 'inline' |,'capture'.'inline'. summary returns a compact response with a data_preview block; inline returns the fullpayload; capture writes the full payload to this server's local disk for the chart-render pipeline and returns a capture_ref URI. capture is available on the local stdio transport only, and the hosted HTTP transport rejects it with a structured error naming 'summary' and 'inline' as the valid alternatives, since a capture_ref would be a dead link for a remote caller. Optional; defaults to 'summary' when omitted.payload.","typeenum":["stringsummary","nullinline"],"type":"string"},"per_segment":{"default":null,"description" ⟨186 unchanged words⟩
⟨28 unchanged words⟩ an optional proposed new debt or home price. Pick this to measure DTI ratios and mortgage-program qualification against existing debts; pick `compare_debt_consolidation` when the question is whether a consolidation loan costs less than keeping the current credit cards, and pick `rent_vs_buy` when the question is whether to buy a home at all rather than what DTI a given price implies. Returns current DTI, front-end and back-end ratios with ⟨34 unchanged words⟩ rule (Fannie Mae) for debts near payoff.qualification.<program>.qualification_status`qualification.<program>.qualification_status` is a tri-state verdict ('qualifies' | 'underwriting_dependent' | 'ineligible'): - 'underwriting_dependent' means the manual-underwriting baseline is exceeded but further underwritingmaycan still approve it, an automated-underwriting system for ⟨23 unchanged words⟩ VA (never an automated decision), soqualification.<program>.qualifies=false`qualification.<program>.qualifies=false` does NOT by itself mean the borrower isblocked.blocked - Read qualification_status, not the bare qualifies boolean, for the real answer;qualification.<program>.note`qualification.<program>.note` explains the specific underwriting or hard-cap context, naming which mechanismapplies.applies - VA's back-end overage alone never returns 'ineligible' either ⟨26 unchanged words⟩ VA and USDA are each disclosure-only above theirbaselines.baselines
⟨65 unchanged words⟩ and time-to-target at the supplied monthly savings cadence. Pick this to size an emergency-fund target; pick `calculate_runway` when savings are already fixed and the question is how many months they will last, not what the target is. Pairs with debt-payoff content for the recurring 'save ⟨12 unchanged words⟩ below the 3-month personal-finance minimum, never above12 (excess cash is better invested than parked).12.
⟨5 unchanged words⟩ a professional before acting. Standard amortizing loan calculator. Pick this for a single fixed-rate installment loan (mortgage, auto, student, personal) with one amortization schedule; pick `calculate_cc_payoff` for a credit card, which carries revolving balances, multiple APR segments, and a snowball or avalanche strategy this tool does not model. Returns: - monthly payment, total interest, and a payoff date (null when the loan does not clear within its term), and- a bucketed Analysis suitable for chart rendering. The Analysis includes KPIs, annotations (e.g. crossover month), and summarystrings.strings When extra_monthly_payment is supplied, every computed figure in ⟨23 unchanged words⟩ under analysis; a warnings[] entry names this.The response includes `chart_hints` with rendering directives any ⟨5 unchanged words⟩ MCP server renders them locally over stdio only.On the local stdio transport, use output: 'capture' when passing the result to a chart tool to avoid filling the LLM context with bucket data; the hosted HTTP transport rejects 'capture' with a structured error, so use 'summary' (default; the full payload is already returned inline) there instead.This tool does not support output: 'inline' on any transport.
⟨121 unchanged words⟩ "string","null"]},"output":{"default":null,"description":"Valid values: 'summary' (default)or 'capture'. 'inline' is not a valid value for this tool on any transport.. 'summary' returns the full payload including analysis.buckets[] inline.'capture' writes the full payload to ~/.senaro/captures/ and returns capture_ref, stripping analysis from the wire response; available on the local stdio transport only, since the hosted HTTP transport rejects 'capture' and names 'summary' as the only alternative.","typeenum":["stringsummary"],"nulltype"]:"string"},"principal":{"description":"Loan principal ⟨30 unchanged words⟩
⟨117 unchanged words⟩ (conservative). All assumptions cite their source.HEAVY tool: use output='summary' (default)Pickforthisthetoheadlineprojectorhowoutput='inline'manyformonthsthecurrentfullsavingsschedule.willoutput='capture'lastwritesagainsttheexpensesfullandpayloadinflows;topicka`calculate_emergency_fund`filewhenonthethisquestionserver'sislocalthediskfund'sfortargetthesize,chart-rendernotpipeline;howavailablelongonitthelasts.localHEAVYstdiotool:transportuseonly,output='summary'and(default)rejectedforwiththeaheadlinestructuredorerroroutput='inline'onfor thehosted HTTPfulltransport.schedule.
⟨183 unchanged words⟩ "number","null"]},"output":{"default":null,"description":"Valid values: 'summary' (default),'inline', or 'capture'.'inline'. 'summary' returns headline scalars (depletion month or ⟨12 unchanged words⟩ including the month-by-month schedule[] for chart rendering.'capture' writes the full payload to ~/.senaro/captures/ and returns capture_ref; available on the local stdio transport only, since the hosted HTTP transport rejects 'capture' and names 'summary' and 'inline' as the valid alternatives.","typeenum":["stringsummary","nullinline"],"type":"string"},"use_essential_expenses":{"default":null,"description" ⟨33 unchanged words⟩
Calculation, not advice. Verify with a professional before acting.Should you consolidate credit card debt with a personal loan?Compares keeping cards vs. consolidation loan vs. optional ⟨76 unchanged words⟩ Works with multiple cards including cash advance balances. Pick this to weigh a consolidation loan (required input), plus any balance-transfer offers, against keeping current cards; pick `calculate_cc_payoff` for a single payoff timeline with no consolidation option, and pick `compare_strategies` to compare avalanche against snowball ordering on the cards as they stand. The response includes `chart_hints` with rendering directives any ⟨20 unchanged words⟩ headline comparison or output='inline' for the full payload.output='capture' writes the full payload to a file on this server's local disk for the chart-render pipeline; available on the local stdio transport only, and rejected with a structured error on the hosted HTTP transport.
⟨1130 unchanged words⟩ ,000, applied on top of the requiredminimums.minimums for keep-cards and any balance transfer, and on top of the loan's own required payment for consolidation. Optional; defaults to 0 when omitted. fixed_payments is ⟨99 unchanged words⟩ "boolean","null"]},"output":{"default":null,"description":"ResponseValidverbosityvalues: 'summary' (default)| 'inline' |,'capture'.'inline'. summary: compact response with a data_preview block; ⟨28 unchanged words⟩ heavy array is added for chart rendering).capture: full payload written to this server's local disk for the chart-render pipeline; capture_ref URI returned. Available on the local stdio transport only; the hosted HTTP transport rejects 'capture' with a structured error naming 'summary' and 'inline' as the valid alternatives. Optional; defaults to 'summary' when omitted.","typeenum":["stringsummary","nullinline"],"type":"string"},"windfalls":{"default":null,"description" ⟨61 unchanged words⟩ scenarios use with-windfalls totals so cross-option ranking staysapples-to-apples.apples-to-apples, except what_if.same_budget_accelerated, a windfall-free hypothetical about extra-payment behavior, not your actual lump-sum schedule.","items":{"properties":{"amount": ⟨80 unchanged words⟩
⟨77 unchanged words⟩ Protection Act, and after-tax net worth comparison. Pick this to compare two mortgage structures on a purchase, such as 15 versus 30 year or points versus no points; pick `refi_breakeven` when the comparison is against your existing loan and a refinance offer, and pick `compare_strategies` when the question is payoff strategy on revolving debt, not a mortgage term. Note: ARM (adjustable-rate) mortgages are not yet supported.
⟨763 unchanged words⟩ removed at the 78% HPA automatic-termination threshold instead.WhenThe rejection guard applies only when pmi_monthly is above 0 and the loan's own initialloan-to-valueLTV is above 80 percent, the range where PMI applies: there, a value at or above that initial ⟨20 unchanged words⟩ be modeled for any month of the loan.AtWhenorpmi_monthlybelowis80omittedpercentor 0, no such checkruns.runs, whatever the LTV, and the supplied value is accepted but changes nothing in the response, because no PMI is modeled in that case. Either way PMI also stops at the statutory ⟨203 unchanged words⟩
⟨8 unchanged words⟩ acting. Compare avalanche and snowball payoff strategies side-by-side. Pick this to compare avalanche against snowball ordering on the same set of cards; pick `calculate_cc_payoff` once a strategy is chosen and the need is a single payoff timeline with windfalls or fixed payments. Returns months, total interest, payoff order, savings ⟨326 unchanged words⟩ MCP server renders them locally over stdio only.output: 'capture' is available on the local stdio transport only, and is rejected with a structured error on the hosted HTTP transport, where a capture_ref would be a dead link for a remote caller; see the output parameter for the response verbosity modes.This tool takes no strategy, fixed_payments, full_schedule ⟨20 unchanged words⟩
⟨1882 unchanged words⟩ "number","null"]},"output":{"default":null,"description":"ResponseValidverbosityvalues: 'summary' (default)| 'inline' |,'capture'.'inline'. summary returns the headline comparison with a data_preview block; inline returns the fullpayload; capture writes the full payload to this server's local disk for the chart-render pipeline and returns a capture_ref URI. capture is available on the local stdio transport only, and the hosted HTTP transport rejects it with a structured error naming 'summary' and 'inline' as the valid alternatives, since a capture_ref would be a dead link for a remote caller. Optional; defaults to 'summary' when omitted.payload.","typeenum":["stringsummary","nullinline"],"type":"string"}},"required":["cards"],"type":"object"}
⟨36 unchanged words⟩ list), computes: the annual match youare capturingreceive today; the maximumyou couldmatchcaptureavailable (full match entitlement); the match forfeited at your current rate; the minimum contribution percent tocapturereceive the full match; whether front-loading contributions would forfeit ⟨9 unchanged words⟩ showing level vs. front-load paths side by side. Pick this to size 401(k) contributions against the employer match formula; pick `payoff_vs_invest` when the question is putting an extra monthly amount toward a debt versus investing it (that tool takes no employer-match input), not how much of the match to receive. IRS limits (402(g) elective deferral, 401 ⟨66 unchanged words⟩ scalars or output='inline' for the full per-period schedule.output='capture' writes the full payload to a file on this server's local disk for the chart-render pipeline; available on the local stdio transport only, and rejected with a structured error on the hosted HTTP transport.
⟨235 unchanged words⟩ "array","null"]},"output":{"default":null,"description":"ResponseValidenvelope.values: 'summary' (default), 'inline'. Response envelope. 'summary': headline scalars, period_schedule stripped. 'inline': full payload including period_schedule[].'capture': full payload written to ~/.senaro/captures/, capture_ref URI returned; local stdio transport only, rejected with a structured error on the hosted HTTP transport naming 'summary' and 'inline' as the valid alternatives.","typeenum":["stringsummary","nullinline"],"type":"string"},"participant_age":{"default":null,"description" ⟨59 unchanged words⟩
Calculation, not advice. Verify with a professional before acting.Should you pay extra on debt or invest the difference?Compares the guaranteed return of debt payoff against ⟨26 unchanged words⟩ , student loans, personal loans, and mortgages. Pick this when the alternative to investing is paying down an existing debt balance; pick `calculate_opportunity_cost` when there is no debt in the picture and the alternative is simply forgoing recurring spending to invest it instead. The response echoes debt_type (canonical lowercase enum the ⟨23 unchanged words⟩ comparison or output='inline' for the full month-by-month schedule.output='capture' writes the full payload to a file on this server's local disk for the chart-render pipeline; available on the local stdio transport only, and rejected with a structured error on the hostedWhenHTTPnotransport.projectionAtcanextremebeinputscomputed (very long horizon, very high rate, or very large amounts), the responsemay instead beis { meta, not_representable: { code, explanation } }when no projection can be computed.instead.
⟨221 unchanged words⟩ "number","null"]},"output":{"default":null,"description":"Valid values: 'summary' (default),'inline', or 'capture'.'inline'. 'summary' returns headline comparison scalars, milestones, and ⟨6 unchanged words⟩ the full payload including the month-by-month monthly_schedule[].'capture' writes the full payload to ~/.senaro/captures/ and returns capture_ref; available on the local stdio transport only, since the hosted HTTP transport rejects 'capture' and names 'summary' and 'inline' as the valid alternatives.","typeenum":["stringsummary","nullinline"],"type":"string"},"tax_bracket_pct":{"default":null,"description" ⟨79 unchanged words⟩
⟨102 unchanged words⟩ and tax effects are out of scope). Pick this when refinancing your existing mortgage into a new rate and term is the question; pick `compare_mortgage_terms` when comparing two mortgage structures on a purchase you have not yet taken out. All defaults cite primary sources (LodeStar/ALTA closing-cost data ⟨9 unchanged words⟩
⟨108 unchanged words⟩ Pub. L. 119-21) and can be overridden.HEAVY tool: use output='summary'Pick(default)this forscalartheheadlinebuy-vs-rentortenureoutput='inline'decision;forpickchart`compare_mortgage_terms`series.whenoutput='capture'youwritesarethealreadyfullbuyingpayloadandtocomparingatwofilemortgageonstructures,this`compare_strategies`server'stolocalorderdiskcredit-cardforpayoff,theandchart-render`payoff_vs_invest`pipeline;toavailableweighonextrathedebtlocalpaymentsstdioagainsttransportinvesting.only,HEAVYandtool:rejectedusewithoutput='summary'a(default)structuredforerrorscalaronheadlinetheorhostedoutput='inline'HTTPfortransport.chart series.
⟨908 unchanged words⟩ "number","null"]},"output":{"default":null,"description":"Valid values: 'summary' (default),'inline', or 'capture'.'inline'. 'summary' returns headline scalars and per-horizon snapshots with ⟨10 unchanged words⟩ yearly_series[] and monthly_series[] for chart rendering.'capture' writes the full payload to ~/.senaro/captures/ and returns capture_ref; available on the local stdio transport only, since the hosted HTTP transport rejects 'capture' and names 'summary' and 'inline' as the valid alternatives.","typeenum":["stringsummary","nullinline"],"type":"string"},"pmi_annual":{"default":null,"description" ⟨106 unchanged words⟩ of 78% or your value is reached first. The rejection guard applies only when down_payment_pct is below 20 and the resolved pmi_pct is above 0, the range where PMI applies: there, a value at or above the loan's own initial LTV is rejected, because the requested removal point would already be met at the first payment, so no PMI would be modeled for any month of the loan. When the resolved pmi_pct is 0, or down_payment_pct is 20 or more, no such check runs, whatever the LTV. Either way PMI also stops at the statutory ⟨260 unchanged words⟩
⟨135 unchanged words⟩ the broader refinance / pay-extra / drop-PMI decision. Scope: conventional mortgages only; FHA loans use MIP (Mortgage Insurance Premium) with different rules. Typically MIP runs for the life of the loan when down payment < 10%. This tool does not model MIP.
{"properties":{"toolArgumentsannual_pmi_rate_pct":{"default":null,"description":"JSONAnnualobjectPMIwithastheseaparameters:\n\ncurrent_balance:percentagedecimalof>the current loan balance. Decimal from 0(REQUIRED).toToday's5.loanOptional;balance.\noriginal_purchase_priceomitting it uses the cited 0.5 default. Typical conventional-loan PMI ranges from 0.3% to 1.5%.","type":["number","null"]},"annual_rate_pct":{"description":"MortgagedecimalAPR>as a percentage. Decimal from 0(REQUIRED).toWhat20.youREQUIRED,paidno default.","type":"number"},"chart_title":{"default":null,"description":"Override for thehomechart(thetitle.purchase-priceMustsidenotofcontaintheem-dashesHPAorbasis;en-dashes.whenMaxa120closingcharacters.appraisalOptional.","type":["string","null"]},"current_balance":{"description":"Today'sisloanlowerbalance. Decimal,seegreateroriginal_appraised_value).\ncurrent_home_valuethan 0. REQUIRED, no default.","type":"number"},"current_home_value":{"default":null,"description":"Currentdecimalmarket>value0of(optional).the home. Decimal, greater than 0. Optional. Whenprovidedsupplied AND greater than the HPA original value ( ⟨22 unchanged words⟩ on current market value with a fresh appraisal).\noriginal_appraised_value.","type":["number","null"]},"extra_monthly_payment":{"default":null,"description":"Extradecimalprincipal>paid0each(optional).monthThebeyondhome'stheappraisedregularvaluepayment.atDecimal,closing.atHPAleastsets0.theOptional;PMIdefaultstriggertobasis0towhentheomitted.","type":["number","null"]},"loan_age_months":{"default":null,"description":"MonthsLESSERelapsedofsincepurchaseorigination.priceIntegerandfromthis0appraisalto(12480.U.S.C.Optional.4901);Cannotprovideexceeditoriginal_loan_term_months whenyourbothclosingareappraisalsupplied.cameSupplyingineitherbelowone without thepurchaseotherprice.\nannual_pmi_rate_pct:isdecimalrejected;0-5both(optionalare required together. See original_loan_term_months.","type":["integer","null"]},"monthly_payment":{"description":"CurrentdefaultP&I0.5).monthlyAnnualpayment,PMIexcludingastax,ainsurance,percentageandofPMI.theDecimal,currentgreaterloanthanbalance.0.TypicalREQUIRED,conventional-loannoPMIdefault.","type":"number"},"original_appraised_value":{"default":null,"description":"Therangeshome'sfromappraised0.3%valuetoat1.5%.\nannual_rate_pct:closing.decimalDecimal,0-20greater(REQUIRED).thanMortgage0.APR.\nmonthly_payment:Optional.decimalHPA>sets0the(REQUIRED).PMICurrenttriggerP&Ibasismonthlytopaymentthe(excludingLESSERtax/insurance/PMI).\nextra_monthly_payment:ofdecimalpurchase>=price0and this appraisal (optional,12defaultU.S.C.04901).;Extrasupplyprincipaliteachwhenmonthyourbeyondclosingtheappraisalregularcamepayment.\noriginal_loan_term_months:inintegerbelow1-480the(optional).purchase price.","type":["number","null"]},"original_loan_term_months":{"default":null,"description":"The loan's original term in months. Integer from 1 to 480. Optional. Supplied together with loan_age_months, this computes the 12 ⟨34 unchanged words⟩ without the other is rejected; both are requiredtogether.\nloan_age_monthstogether.","type":["integer0-480 (optional). Months elapsed since origination. Cannot exceed original_loan_term_months when both are supplied. Supplying either one without the other is rejected; both are required together. See original_loan_term_months.\n\nScope","null"]},"original_purchase_price":conventional mortgages only. FHA loans use MIP (Mortgage Insurance Premium) with different rules. Typically{"description":"WhatMIPyourunspaid for thelife ofhome (theloanpurchase-pricewhensidedownofpaymentthe<HPA10%.basis;ThiswhentooladoesclosingNOTappraisalmodelisMIP.\nchart_title:lower,stringsee(optionaloriginal_appraised_value)override for the chart title. Must not.containDecimal,em-dashesgreaterorthanen-dashes.0.MaxREQUIRED,120nocharacters.default.","type":"number"}},"required":["toolArgumentscurrent_balance","original_purchase_price","annual_rate_pct","monthly_payment"],"type":"object"}
⟨198 unchanged words⟩ MCP server renders them locally over stdio only.Useoutput:'summary' (default) for a compact response or 'inline' for the full payload. output:'capture'writes the full payload to a file on this server's local disk and returns a capture_ref URI for chart rendering;is available on the local stdio transport only, and is rejected with a structured error on the hosted ⟨5 unchanged words⟩ would be a dead link for a remotecaller.caller; see the output parameter for the response verbosity modes. Top-level `entered_starting_balance` echoes the caller's supplied balances by ⟨128 unchanged words⟩
before
{"properties":{"toolArguments":{"description":"JSON object with these parameters:\n\ncards (REQUIRED array, max 20):\n - name: string (optional, auto-generated if omitted)\n - purchase_balance: decimal >= 0 (REQUIRED unless segments[] is supplied)\n - purchase_apr_pct: decimal 0-100 as percentage, e.g. 24.99 not 0.2499 (REQUIRED unless segments[] is supplied)\n - cash_advance_balance: decimal >= 0 (optional, default 0)\n - cash_advance_apr_pct: decimal > 0, <= 100 (required only if cash_advance_balance > 0)\n - minimum_payment: decimal >= 0 (optional, omit or set 0 to auto-calculate). Binds ONLY when fixed_payments = true: the card is then locked at max(minimum_payment, that card's issuer minimum computed at month 1), and that locked amount is paid every month. On the DEFAULT path (fixed_payments = false), this value is NOT used: the plan recomputes each card's issuer minimum from its current balance every month, so the monthly budget is the sum of those recomputed minimums plus extra_monthly_payment. To hold a stated payment instead, set fixed_payments = true.\n - annual_fee: decimal >= 0 (optional, default 0). Charged at month 1 and every 12th month thereafter while the card has a balance.\n - plan_fees_monthly: decimal >= 0 (optional, default 0). Charged every month while the card has a balance (e.g. pay-over-time plan fee).\n - segments: array (OPTIONAL; when present, supersedes purchase_balance / cash_advance_balance). Max 100 segments total across all cards in the request. Per-card, per-type caps: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan. Each item:\n - type: 'purchase' | 'cash_advance' | 'balance_transfer' | 'promotional' | 'installment_plan' (REQUIRED). Use 'promotional' for a balance whose 0% (or below-market) intro APR reverts to a standard rate later and is NOT a balance transfer, e.g. a 0% intro purchase APR; it validates and reverts identically to balance_transfer.\n - balance: decimal >= 0 (REQUIRED)\n - apr_pct: decimal 0-100 (REQUIRED for purchase / cash_advance / balance_transfer / promotional; must be 0 for installment_plan; for cash_advance, must be > 0 when balance > 0, since cash advances have no promotional 0% product)\n - revert_apr_pct: decimal 0-100 (REQUIRED for balance_transfer / promotional; APR after promo expires; not applicable to purchase / cash_advance (silently ignored); REJECTED on installment_plan (FIELD_NOT_ALLOWED_HERE) since installment_plan has no post-term-rate concept: an expired plan's residual keeps its existing rate)\n - promo_expires_month: int >= 1 (REQUIRED for balance_transfer / promotional; month at which apr_pct flips to revert_apr_pct)\n - monthly_fee: decimal >= 0 (REQUIRED for installment_plan; fixed fee charged each month while the plan's term is active; stops accruing once the term elapses)\n - plan_payment_due: decimal > 0 (REQUIRED for installment_plan; locked monthly payment, principal + monthly_fee; keeps being charged every month even after the term elapses, until the balance clears)\n - remaining_payments: int >= 0 (optional, installment_plan only). 0 means the plan's stated term has ALREADY ended: this is the correct, valid way to model an already-expired plan carrying a residual balance, and it is accepted regardless of balance (an expired plan's residual is a real state, not a data-entry error). When remaining_payments >= 1, it must be consistent with balance / plan_payment_due / monthly_fee: net = plan_payment_due - monthly_fee must be positive, or the plan could never amortize (rejected as INSTALLMENT_PLAN_NET_NOT_POSITIVE); balance must be <= remaining_payments * net (the plan must be able to clear within its stated term) and balance must be > (remaining_payments - 1) * net (the term must not be overstated), either violation rejected as INSTALLMENT_PLAN_TERM_MISMATCH. If a plan has already ended, enter remaining_payments as 0 rather than a positive count that cannot clear the balance. An expired plan (remaining_payments reaches 0 with a positive balance still owed, whether supplied that way or reached by simulation) does not freeze and is never repriced: it keeps receiving its locked plan_payment_due every month at its existing rate until the balance clears. One aggregated PLAN_TERM_ELAPSED_WITH_BALANCE warning fires per card (never one per segment), naming every affected plan on that card and its residual, plus the card total.\n - merchant_name: string (optional, installment_plan only)\n - min_payment_order: int >= 1 (optional; the minimum first pays any installment_plan segment's locked plan_payment_due in full, structurally, regardless of APR or this value; among the remaining (revolving) segments it then pays down the lowest-current-APR segment first, issuer practice, not statutorily regulated; this value only breaks a tie between segments that share both the exact same current APR AND the same installment-plan status, in which case the higher-balance segment wins; two segments on the same card sharing a value emit a DUPLICATE_PAYMENT_ORDER warning; a supplied value with no APR-tie partner to ever decide emits PAYMENT_ORDER_NOT_DECISIVE)\n - extra_payment_order: int >= 0 (optional; 0 = SKIP -- this segment never receives extra payment, the default for installment_plan; a positive value only breaks a tie between segments that share the exact same current APR, since the Credit CARD Act (TILA §164(b), 15 U.S.C. §1666c(b)) / 12 CFR §1026.53(a) always pays the highest-current-APR segment first regardless of this value; two segments on the same card sharing a positive value emit a DUPLICATE_PAYMENT_ORDER warning, duplicate 0s never warn; a supplied value with no APR-tie partner to ever decide emits PAYMENT_ORDER_NOT_DECISIVE -- this hits installment_plan hardest, since it is pinned at 0% APR (apr_pct is not read for this segment type), so a positive override on it can win the tie-break only against another segment also at exactly 0%; whenever any positive-APR segment shares the card, the plan stays ELIGIBLE and sorts LAST behind every positive-APR segment, receiving extra only once those higher-APR balances clear)\n Response gains per-card interest_saving_balance (sum of APR-bearing segments) and installment_balance_locked (sum of installment_plan segments) when segments[] is supplied.\n\nextra_monthly_payment: decimal >= 0 (optional, default 0)\nstrategy: 'avalanche' | 'snowball' (optional, default 'avalanche')\nfixed_payments: bool (optional, default false). When true, each card's payment is locked at max(cards[].minimum_payment, that card's issuer minimum computed at month 1), and the total monthly budget (sum of those locked amounts plus extra_monthly_payment) is held constant for the whole payoff, so once a card is paid off its freed-up payment rolls forward onto the remaining cards. This is the ONLY mode in which cards[].minimum_payment affects the result; see the minimum_payment field above for what happens on the default path.\napply_rate_cap: bool (optional, default false)\nfull_schedule: bool (optional, default false). The per-card monthly_schedule is capped at 1000 rows total (cards x months); on a long multi-card payoff later months are omitted from monthly_schedule. The portfolio-level monthly_totals series is always complete, so read monthly_totals for the full timeline.\nper_segment: bool (optional, default true)\ninclude_card_timeline: bool (optional, default false)\n\nwindfalls: array of one-time principal payments (optional, default empty, max 12 items). Each item:\n - month: int >= 0 (REQUIRED). 0 means applied before month 1's interest (same as reducing starting principal). N >= 1 applies at the END of calendar month N, so month N+1's interest is calculated on the post-windfall balance.\n - amount: decimal > 0 (REQUIRED).\n - label: string (optional). e.g. 'Tax refund', 'Year-end bonus'.\nWhen any windfalls are present the response gains: baseline, with_windfalls, months_saved_vs_baseline, interest_saved_vs_baseline, windfalls_applied[], windfalls_unused[]. Empty windfalls yields the same response shape as before.\n\nMin-payments-only baseline (v1.7, gap #593): when extra_monthly_payment > 0, windfalls are present, or fixed_payments = true, the response also gains:\n - min_payments_only: { months, interest_cost, amount_paid, payoff_date } - what happens paying minimums only\n - interest_saved_vs_min_payments: decimal - total interest saved vs paying minimums only (always >= 0)\n - months_saved_vs_min_payments: int - months saved vs paying minimums only (when minimums never pay off, capped at MaxMonths minus with-plan months)\nTrivial minimums-only calls (no extra, no windfalls, not fixed) keep their current response shape unchanged.\n\nMinimums-only baseline series (v1.9, B2; bucketed v2.5, #1108): under the same plan-exists condition as min_payments_only above, the response also gains minimums_only_baseline: { months, granularity, buckets[], payoff_date } - the minimums-only balance trajectory bucketed through the same shared aggregator as analysis.buckets[] (same bucket row shape: bucket_index, label, plus the 17 money fields), with granularity auto-selected from THIS series' own term, the same standard rule analysis.granularity itself uses. minimums_only_baseline.granularity is NOT guaranteed to equal analysis.granularity: each series auto-selects independently from its own term, so read each series' own granularity rather than assuming they match. Equal bucket-array length is NOT a valid signal that the two granularities match either: a 24-month primary run (monthly, 24 buckets) and a 24-year minimums-only baseline (yearly, 24 buckets) land on the SAME buckets[].length with DIFFERENT granularities. granularity is the only valid mismatch signal; length is not. Computed from the SAME gated simulation as min_payments_only, so months/payoff_date agree between the two blocks. Absent under the identical trivial-call condition as min_payments_only.\n\nchart_title: string (optional) override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters.\noutput: 'summary' | 'inline' | 'capture' (optional, default 'summary')\n 'capture' is available on the local stdio transport only; the hosted HTTP transport rejects it with a structured error naming 'summary' and 'inline' as the valid alternatives."}},"required":["toolArguments"],"type":"object"}after
{"properties":{"apply_rate_cap":{"default":null,"description":"Whether to cap each card's APR at the regulatory ceiling before simulating. Optional; defaults to false when omitted.","type":["boolean","null"]},"cards":{"description":"Credit cards to pay off, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards is required and must be an array.\"); the two are not the same rejection. Every card may carry segments[]. Max 100 segments total across all cards in the request. Per-card, per-type caps: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan.","items":{"properties":{"annual_fee":{"description":"Annual fee in dollars, $0 to $1,000,000,000. Optional; defaults to 0. Charged at month 1 and every twelfth month after, while the card carries a balance.","type":["number","null"]},"cash_advance_apr_pct":{"description":"Cash advance APR as a percentage, greater than 0 and up to 100. Required when cash_advance_balance is greater than 0: cash advances have no promotional 0% product, so a 0% rate on a real advance balance is a data-entry error.","type":["number","null"]},"cash_advance_balance":{"description":"Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted. A POSITIVE value alongside a non-empty segments[] is rejected, the same way purchase_balance is. An explicit 0 is accepted.","type":["number","null"]},"minimum_payment":{"description":"Minimum payment in dollars, $0 to $1,000,000,000 (optional, omit or set 0 to auto-calculate). Where it binds, the card is locked at max(minimum_payment, that card's issuer minimum computed at month 1), and that locked amount is paid every month. On calculate_cc_payoff it binds ONLY when fixed_payments = true; on the DEFAULT path (fixed_payments = false) it is NOT used, because the plan recomputes each card's issuer minimum from its current balance every month, and the response discloses that as MINIMUM_PAYMENT_NOT_BINDING. On compare_strategies there is no fixed_payments parameter and supplying one is rejected: the avalanche and snowball arms ALWAYS run locked, so the value DOES bind and moves both arms, while the minimum-payments-only baseline always recomputes and ignores it, disclosed as MINIMUM_PAYMENT_NOT_BINDING_IN_BASELINE.","type":["number","null"]},"monthly_spend":{"description":"Recurring monthly purchase amount charged to this card's purchase balance before interest accrues, $0 to $50,000 per month. Optional; defaults to 0. Use the segment-level monthly_spend instead when supplying segments[].","type":["number","null"]},"name":{"description":"Card label, e.g. 'Chase Sapphire', 120 characters or fewer. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', and so on). Echoed into per-card results and warning text. A name over the cap is replaced in error field paths by a key built from its zero-based card index, written as '#0 (name over cap)', '#1 (name over cap)' and so on.","type":["string","null"]},"plan_fees_monthly":{"description":"Recurring monthly card fee in dollars, $0 to $1,000,000,000, e.g. a pay-over-time plan fee. Optional; defaults to 0. Charged every month while the card carries a balance.","type":["number","null"]},"purchase_apr_pct":{"description":"Purchase APR as a percentage, 0 to 100, e.g. 24.99 not 0.2499. Required when purchase_balance is greater than 0: an omitted APR would silently compute $0 interest.","type":["number","null"]},"purchase_balance":{"description":"Purchase balance in dollars, $0 to $1,000,000,000. Required unless segments[] carries at least one segment: an omitted purchase_balance would silently report a $0, 0-month payoff. Supplying a POSITIVE value alongside a non-empty segments[] is rejected, since the two would be competing sources for the same balance. An explicit 0 is accepted.","type":["number","null"]},"segments":{"description":"Per-segment breakdown of this card's balances. Optional; when it carries at least one segment it SUPERSEDES purchase_balance and cash_advance_balance, and a POSITIVE value in either of those is rejected. An empty segments[] is treated as absent, so purchase_balance is then required. At most 100 segments across the whole request. Per card, per type: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan. Each item carries its own type, balance, rate and payment priority; see the type field on the item for the per-type field matrix.","items":{"properties":{"apr_pct":{"default":null,"description":"Annual percentage rate for this segment, 0 to 100, e.g. 24.99 not 0.2499. Required when balance is greater than 0 on purchase, cash_advance, balance_transfer and promotional. On cash_advance it must be greater than 0 whenever a balance is carried. Must be 0 on installment_plan, which uses monthly_fee instead, so omitting it there is the correct shape.","type":["number","null"]},"balance":{"description":"Segment balance in dollars, $0 to $1,000,000,000. REQUIRED on every segment type: an omitted balance would silently report a $0, 0-month payoff, so it is rejected instead. An explicit 0 is valid, for example a paid-off balance_transfer segment kept for schedule continuity.","type":"number"},"extra_payment_order":{"default":null,"description":"Extra-payment tie-break priority, 0 or more, where 0 means this segment never receives extra payment. Optional on every type, and the default for installment_plan. Only breaks a tie between segments sharing the exact same current APR, since the Credit CARD Act (TILA §164(b), 15 U.S.C. §1666c(b)) / 12 CFR 1026.53(a) always pays the highest-current-APR segment first regardless of this value.","type":["integer","null"]},"merchant_name":{"default":null,"description":"Label for an installment plan's merchant, 120 characters or fewer. Optional on installment_plan, ignored on every other type.","type":["string","null"]},"min_payment_order":{"default":null,"description":"Minimum-payment tie-break priority, 1 or more. Optional on every type. The minimum first pays any installment_plan's locked plan_payment_due in full, then the lowest-current-APR segment; this value only breaks a tie between segments sharing both the same current APR and the same installment-plan status.","type":["integer","null"]},"monthly_fee":{"default":null,"description":"Fixed fee charged each month while an installment plan's term is active, $0 or more and no greater than plan_payment_due. Optional on installment_plan. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"monthly_spend":{"default":null,"description":"Recurring monthly purchase amount posted to this segment before interest accrues, $0 to $50,000 per month. Optional on purchase. A negative value is rejected as NEGATIVE_BALANCE on every type. On every type other than purchase a positive value is rejected with FIELD_NOT_ALLOWED_HERE, since those balances do not accept new purchases; an explicit 0 is accepted.","type":["number","null"]},"plan_payment_due":{"default":null,"description":"Locked monthly payment for an installment plan, principal plus monthly_fee. Required on installment_plan, greater than $0, at least monthly_fee, and no more than $1,000,000,000. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"promo_expires_month":{"default":null,"description":"Month at which apr_pct flips to revert_apr_pct, 1 to 480. Required on balance_transfer and promotional. Ignored on purchase, cash_advance and installment_plan.","type":["integer","null"]},"remaining_payments":{"default":null,"description":"Payments left in an installment plan's stated term, 0 or more. Optional on installment_plan, ignored on every other type. 0 means the term has ALREADY ended and is valid with any balance, including a positive residual. From 1 up, the balance must be clearable within the stated term and must not be clearable a month early.","type":["integer","null"]},"revert_apr_pct":{"default":null,"description":"Rate this segment reverts to once its promo expires, 0 to 100, and at least apr_pct. Required on balance_transfer and promotional. Ignored on purchase and cash_advance. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate rather than repricing.","type":["number","null"]},"stop_spend_month":{"default":null,"description":"Month index at which recurring spend stops, 0 or more. Read on purchase only, and range checked on every type. Omit to spend for the whole projection.","type":["integer","null"]},"type":{"description":"Segment type. REQUIRED on every segment: omitting it is rejected. Per-type field matrix. Every field below is classified for every segment type: REQUIRED (omitting it is rejected), OPTIONAL (accepted either way and read), IGNORED (accepted and never read for this type, though a value can still fail the field's own range check), or REJECTED (supplying a disallowed value is an error; the field's own rule below says exactly which values are disallowed). Value rules are stated separately from applicability, because a field can be accepted on a type and still be restricted there. The validators are the authority; this matrix describes them.\n- type: REQUIRED on every type. Values: one of purchase, cash_advance, balance_transfer, promotional, installment_plan.\n- balance: REQUIRED on every type. Values: $0 to $1,000,000,000; above $50,000 returns a HIGH_CARD_BALANCE warning, not an error.\n- apr_pct: REQUIRED on purchase, cash_advance, balance_transfer, promotional; OPTIONAL on installment_plan. Values: 0 to 100 as a percentage, e.g. 24.99 not 0.2499. The REQUIRED classification above applies when balance is greater than 0; a zero-balance segment may omit it. Must be greater than 0 on cash_advance carrying a balance. Must equal 0 on installment_plan, where omitting it is the correct shape.\n- revert_apr_pct: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance; REJECTED on installment_plan. Values: 0 to 100, and at least apr_pct. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate.\n- promo_expires_month: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance, installment_plan. Values: 1 to 480.\n- monthly_fee: OPTIONAL on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: $0 or more, and no greater than plan_payment_due, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- plan_payment_due: REQUIRED on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: greater than $0, at least monthly_fee, and no more than $1,000,000,000, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- remaining_payments: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 0 or more. 0 means the stated term has ALREADY ended and is valid with any balance. From 1 up, balance must be clearable within the stated term.\n- min_payment_order: OPTIONAL on every type. Values: 1 or more; breaks a tie only between segments sharing both the same current APR and the same installment-plan status.\n- extra_payment_order: OPTIONAL on every type. Values: 0 or more; 0 means skip. Breaks a tie only between segments sharing the exact same current APR.\n- merchant_name: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 120 characters or fewer.\n- monthly_spend: OPTIONAL on purchase; REJECTED on cash_advance, balance_transfer, promotional, installment_plan. Values: $0 to $50,000 per month. A negative value is rejected as NEGATIVE_BALANCE on every type, purchase included. On every type other than purchase a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; an explicit 0 is accepted.\n- stop_spend_month: OPTIONAL on purchase; IGNORED on cash_advance, balance_transfer, promotional, installment_plan. Values: 0 or more; range checked on every type, read only on purchase.","type":"string"}},"required":["type","balance"],"type":"object"},"type":["array","null"]},"stop_spend_month":{"description":"Month index at which this card's recurring spend stops, 0 or more. Optional; omit to spend for the whole projection.","type":["integer","null"]}},"type":"object"},"type":"array"},"chart_title":{"default":null,"description":"Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.","type":["string","null"]},"extra_monthly_payment":{"default":null,"description":"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums. Optional; defaults to 0 when omitted.","type":["number","null"]},"fixed_payments":{"default":null,"description":"Whether to hold each card's payment constant for the whole payoff. Optional; defaults to false when omitted. When true, each card's payment is locked at max(cards[].minimum_payment, that card's issuer minimum computed at month 1), and the total monthly budget (those locked amounts plus extra_monthly_payment) is held constant for the whole payoff, so once a card is paid off its freed-up payment rolls forward onto the remaining cards. This is the ONLY mode in which cards[].minimum_payment affects calculate_cc_payoff's result; compare_strategies has no fixed_payments parameter and binds minimum_payment on both of its strategy arms regardless.","type":["boolean","null"]},"full_schedule":{"default":null,"description":"Whether to return the full per-card month-by-month schedule. Optional; defaults to false when omitted. The per-card monthly_schedule is capped at 1000 rows total across cards and months, so later months are omitted on a long multi-card payoff; the portfolio-level monthly_totals series is always complete and is the one to read for the whole timeline.","type":["boolean","null"]},"include_card_timeline":{"default":null,"description":"Whether to add the card_timeline block, a per-card view of when each card clears. Optional; defaults to false when omitted.","type":["boolean","null"]},"output":{"default":null,"description":"Response verbosity: 'summary' (default) | 'inline' | 'capture'. summary returns a compact response with a data_preview block; inline returns the full payload; capture writes the full payload to this server's local disk for the chart-render pipeline and returns a capture_ref URI. capture is available on the local stdio transport only, and the hosted HTTP transport rejects it with a structured error naming 'summary' and 'inline' as the valid alternatives, since a capture_ref would be a dead link for a remote caller. Optional; defaults to 'summary' when omitted.","type":["string","null"]},"per_segment":{"default":null,"description":"Whether each schedule row carries its per-segment breakdown. Optional; defaults to true when omitted.","type":["boolean","null"]},"strategy":{"default":null,"description":"Payoff order: 'avalanche' pays the highest APR first, 'snowball' the smallest balance first. Optional; defaults to 'avalanche' when omitted. Matched case-insensitively, and the response echoes the canonical lowercase form actually simulated.","type":["string","null"]},"windfalls":{"default":null,"description":"One-time principal payments, at most 12, e.g. a tax refund or a year-end bonus. Optional; a JSON null is treated as omitted. When non-empty the response gains baseline, with_windfalls, months_saved_vs_baseline, interest_saved_vs_baseline, windfalls_applied[] and windfalls_unused[]; an empty array returns the same shape as omitting it.","items":{"properties":{"amount":{"description":"Dollar amount of the windfall, greater than 0. Required per entry.","type":["number","null"]},"label":{"description":"Optional label for this windfall, e.g. 'Tax refund' or 'Year-end bonus'. Max 120 characters.","type":["string","null"]},"month":{"description":"Month index the windfall is applied, 0 or more. 0 means applied before month 1's interest; N >= 1 applies at the end of calendar month N. Required per entry.","type":["integer","null"]}},"type":["object","null"]},"type":["array","null"]}},"required":["cards"],"type":"object"}before
{"properties":{"toolArguments":{"description":"JSON object with these parameters:\n\ngross_monthly_income: decimal > 0 (REQUIRED; OR provide annual_income instead)\nannual_income: decimal > 0 (alternative to gross_monthly_income; divided by 12)\nadditional_income: decimal >= 0 (optional, default 0; side income, rental income, bonuses. Monthly.)\n\nexisting_debts: array of debt objects (optional, can be empty):\n - name: string (optional label, e.g. 'Car Loan')\n - type: 'auto' | 'student' | 'credit_card' | 'personal' | 'mortgage' | 'heloc' | 'child_support' | 'other'\n - monthly_payment: decimal > 0 (REQUIRED per debt)\n - balance: decimal (optional; for payoff cost analysis in what-if scenarios)\n - apr_pct: decimal 0-100 as PERCENTAGE (optional)\n - months_remaining: int (optional; used for 10-month rule exclusion)\n\nproposed_debt: object (optional; OR use proposed_home_price instead):\n - name: string (optional)\n - type: 'auto' | 'student' | 'credit_card' | 'personal' | 'mortgage' | 'heloc' | 'child_support' | 'other' (optional, default 'mortgage')\n - monthly_payment: decimal > 0 (REQUIRED)\n - includes_tax_insurance: bool (optional, default true; if false and type is mortgage, warns that lenders use PITI)\n\nproposed_home_price: decimal > 0 (optional; auto-calculates full PITI. Cannot combine with proposed_debt.)\nproposed_down_payment_pct: decimal 0-99.9 as PERCENTAGE (optional, default 20)\nproposed_rate_pct: decimal 0-20 as PERCENTAGE (optional, default 7.0 with warning)\nproposed_term_years: int 1-40 (optional, default 30)\n\nproperty_tax_annual: decimal >= 0 (optional. For the PITI estimate, uses 0.88% national average if omitted)\nhome_insurance_annual: decimal >= 0 (optional. Uses 0.65% national average if omitted)\npmi_monthly: decimal >= 0 (optional. Auto-estimated at 0.5% of loan when LTV > 80%. Feeds the\n conventional-basis PITI, so it moves with_proposed.front_end_dti, with_proposed.back_end_dti,\n with_proposed.front_end_breakdown, the conventional qualification row, and\n what_if.scenarios[].new_front_end_dti / new_back_end_dti. VA carries no PMI, and FHA/USDA always\n compute their own upfront-plus-annual mortgage insurance instead, at every LTV, never this\n override)\nhoa_monthly: decimal >= 0 (optional, default 0)\n\ninclude_what_if: bool (optional, default true; generate scenarios to improve DTI)\n\ntransaction_purpose: 'purchase' | 'refinance' | 'streamlined_assist' (optional, default 'purchase')\n Affects USDA only, and only what is disclosed. USDA's 32% PITI and 44% Total Debt figures are\n purchase-transaction waiver conditions (HB-1-3555 11.3.A.2), disclosed rather than applied as\n ceilings: Senaro cannot observe how the file is underwritten, so a USDA ratio overage is never 'ineligible'\n on any transaction purpose. For a refinance, 11.3.B states debt ratios 'are not limited to the\n maximum purchase debt ratio thresholds', so where the note fires it names both figures and states that neither applies. Streamlined-assist\n refinances require no debt ratio calculation at all. Conventional, FHA and VA are unaffected.\n\nfamily_size: int 1-20 (optional; must be supplied together with property_state, or neither fires)\nproperty_state: two-letter USPS state code, or 'DC'/'PR'/'GU'/'VI'/'AS'/'MP' (optional; must be supplied together with family_size)\n Together these compute the VA residual income guideline (38 CFR 36.4340(e)) in\n va_residual_income_guideline: the dollar amount VA's tables require for this family size, region,\n and loan amount (derived from proposed_home_price; not computable without it), plus the 38 CFR\n 36.4340(c)(3) review-waiver figure. Computed only for family_size 1-7 and a property_state among\n the 50 states, DC, or PR (not GU, VI, AS, or MP; 38 CFR 36.4340(e) assigns no region to those\n four); outside those bounds, or without proposed_home_price, va_residual_income_guideline.status\n reads 'not_computable' with the reason instead. This block alone is a LOOKUP, not a verdict: it\n never compares against your actual residual income by itself.\n\nmonthly_taxes_and_retirement_withholding: decimal >= 0 (optional; your federal, state, and FICA tax\n withholding, PLUS any amount paid or withheld for retirement, monthly. 38 CFR 36.4340(f)(13)\n treats these as one class of deduction from gross income.)\nmonthly_maintenance_and_utilities: decimal >= 0 (optional; estimated monthly maintenance and utilities\n for the proposed property. 38 CFR 36.4340 calls for a realistic estimate of this figure for the\n property and local utility rates and sets no numeric multiplier itself, but VA underwriting\n guidance (the Lender's Handbook, Pamphlet 26-7) publishes a per-square-foot multiplier for this\n same estimate; applying it needs the property's square footage, which this tool does not\n currently collect, so Senaro has no default to offer here and you supply the aggregate monthly\n amount instead.)\n Supplying BOTH of these, together with proposed_home_price and a computable family_size/\n property_state above, computes qualification.va.residual_income_comparison: your ACTUAL monthly\n residual income, its ratio to the va_residual_income_guideline figure, and whether\n residual_income_meets_review_waiver_margin (residual income at or above 120% of the guideline) is\n met. The shelter expense used here excludes any PMI (VA loans carry no monthly PMI; 38 CFR\n 36.4313(e) sets a funding fee instead, commonly financed into the loan -- see\n va_funding_fee_financed_monthly below). 38 CFR 36.4340(c)(3)'s review-waiver condition is\n CONJUNCTIVE: it also requires the back-end debt-to-income ratio (qualification.va.your_back_end)\n to exceed 41%, which this field does not by itself confirm -- check both fields together. Even\n when both hold, (c)(3) only WAIVES a second-level review requirement; it is not itself an\n approval. Whether this file is actually approved is an underwriting determination Senaro does\n not make and no input combination here determines. Missing any one of the needed inputs reads\n qualification.va.residual_income_comparison.status 'not_computable' with every reason named.\nva_funding_fee_financed_monthly: decimal >= 0 (optional; the additional monthly payment from\n financing a VA funding fee into the loan balance, if any. 38 CFR 36.4313(e)'s applicable\n percentage depends on down payment, prior VA-loan use, and service category, none of which\n Senaro collects, so there is no default; if omitted while any VA figure that depends on it is\n produced -- qualification.va.your_back_end and its verdict, any what_if VA ratio,\n what_if.max_affordable_home.va, or the residual-income comparison above -- a\n VA_FUNDING_FEE_NOT_MODELED warning discloses that no fee is assumed. The home-price-reduction\n what_if scenario's hypothetical price is fixed before the fee is considered, so a supplied fee\n is scaled to that EXACT hypothetical loan size, since 38 CFR 36.4313(e)'s fee is a percentage\n of loan principal. what_if.max_affordable_home.va is a two-pass approximation instead, so its\n supplied fee is scaled to an ESTIMATE of the hypothetical loan size, not the exact figure\n reported; the PMI, tax, and insurance reservation itself is an EXACT closed-form solve, so\n only this fee-scaling step is approximate. Without proposed_home_price there is no reference\n loan size to scale from either way, so the raw fee is reserved unscaled instead and a\n VA_FUNDING_FEE_NOT_SCALED warning discloses it --\n mutually exclusive with VA_FUNDING_FEE_NOT_MODELED by construction, since one requires the fee\n omitted and the other requires it supplied.)"}},"required":["toolArguments"],"type":"object"}after
{"properties":{"additional_income":{"default":null,"description":"Additional monthly income: side income, rental income, or bonuses. Optional; defaults to 0 when omitted. Must be zero or more.","type":["number","null"]},"annual_income":{"default":null,"description":"Annual gross income in dollars, divided by 12 to get monthly income. Exactly one of gross_monthly_income or annual_income is required. Must be at least $0.01, one cent, the smallest amount of money.","type":["number","null"]},"existing_debts":{"default":null,"description":"Existing debts to include in the DTI calculation. Optional; omit it or send an empty array for no existing debts. A JSON null is rejected; omit the field instead. At most 50 debts are allowed.","items":{"properties":{"apr_pct":{"description":"Annual percentage rate, as a percentage (0-100), e.g. 18.5 for 18.5%. Optional.","type":["number","null"]},"balance":{"description":"Current balance in dollars. Optional; used for payoff cost analysis in what-if scenarios.","type":["number","null"]},"monthly_payment":{"description":"Monthly payment in dollars. Required per debt; must be positive.","type":["number","null"]},"months_remaining":{"description":"Months remaining on this debt. Optional; used for the 10-month rule exclusion.","type":["integer","null"]},"name":{"description":"Optional label for this debt, e.g. 'Car Loan'.","type":["string","null"]},"type":{"description":"Debt type: 'auto', 'student', 'credit_card', 'personal', 'mortgage', 'heloc', 'child_support', or 'other'. Optional, defaults to 'other' when omitted; an unrecognized value warns rather than rejects.","type":["string","null"]}},"type":["object","null"]},"type":["array","null"]},"family_size":{"default":null,"description":"Household size for the VA residual income guideline. Supply family_size and property_state together, or neither. Optional; must be between 1 and 20.","type":["integer","null"]},"gross_monthly_income":{"default":null,"description":"Gross monthly income in dollars. Exactly one of gross_monthly_income or annual_income is required. Must be at least $0.01, one cent, the smallest amount of money.","type":["number","null"]},"hoa_monthly":{"default":null,"description":"Monthly homeowners association dues in dollars. Optional; defaults to 0 when omitted. Must be zero or more.","type":["number","null"]},"home_insurance_annual":{"default":null,"description":"Annual home insurance in dollars. Optional; if omitted, estimated at 0.65% of the proposed home price. Must be zero or more.","type":["number","null"]},"include_what_if":{"default":null,"description":"Whether to generate what-if scenarios showing how paying off a debt, increasing income, or reducing the home price would improve DTI. Optional; defaults to true when omitted.","type":["boolean","null"]},"monthly_maintenance_and_utilities":{"default":null,"description":"Estimated monthly maintenance and utilities for the proposed property. 38 CFR 36.4340 calls for a realistic estimate of this figure for the property and local utility rates and sets no numeric multiplier itself, but VA underwriting guidance (the Lender's Handbook, Pamphlet 26-7) publishes a per-square-foot multiplier for this same estimate. Applying it needs the property's square footage, which this tool does not currently collect, so Senaro has no default to offer here and you supply the aggregate monthly amount instead. Supplying BOTH this field and monthly_taxes_and_retirement_withholding, together with proposed_home_price and a computable family_size/property_state, computes qualification.va.residual_income_comparison: your ACTUAL monthly residual income, its ratio to the va_residual_income_guideline figure, and whether residual_income_meets_review_waiver_margin (residual income at or above 120% of the guideline) is met. The shelter expense used here excludes any PMI (VA loans carry no monthly PMI; 38 CFR 36.4313(e) sets a funding fee instead, commonly financed into the loan; see va_funding_fee_financed_monthly for the financed-fee field). 38 CFR 36.4340(c)(3)'s review-waiver condition is CONJUNCTIVE: it also requires the back-end debt-to-income ratio (qualification.va.your_back_end) to exceed 41%, which this field does not by itself confirm. Check both fields together. Even when both hold, (c)(3) only WAIVES a second-level review requirement; it is not itself an approval. Whether this file is actually approved is an underwriting determination Senaro does not make and no input combination here determines. Missing any one of the needed inputs reads qualification.va.residual_income_comparison.status 'not_computable' with every reason named. Optional; must be zero or more.","type":["number","null"]},"monthly_taxes_and_retirement_withholding":{"default":null,"description":"Your federal, state, and FICA tax withholding, plus any amount paid or withheld for retirement, monthly. 38 CFR 36.4340(f)(13) treats these as one class of deduction from gross income. Optional; must be zero or more.","type":["number","null"]},"pmi_monthly":{"default":null,"description":"Monthly PMI (private mortgage insurance) in dollars. Optional; if omitted, auto-estimated at 0.5% of the loan annually when loan-to-value exceeds 80%. Feeds the conventional-basis PITI, so it moves with_proposed.front_end_dti, with_proposed.back_end_dti, with_proposed.front_end_breakdown, the conventional qualification row, and what_if.scenarios[].new_front_end_dti and new_back_end_dti. VA carries no PMI, and FHA and USDA always compute their own upfront-plus-annual mortgage insurance instead, at every loan-to-value, never this override. Must be zero or more.","type":["number","null"]},"property_state":{"default":null,"description":"Two-letter USPS state code, or 'DC'/'PR'/'GU'/'VI'/'AS'/'MP'. Supply family_size and property_state together, or neither. Together these compute the VA residual income guideline (38 CFR 36.4340(e)) in va_residual_income_guideline: the dollar amount VA's tables require for this family size, region, and loan amount (derived from proposed_home_price; not computable without it), plus the 38 CFR 36.4340(c)(3) review-waiver figure. Computed only for family_size 1-7 and a property_state among the 50 states, DC, or PR (not GU, VI, AS, or MP; 38 CFR 36.4340(e) assigns no region to those four); outside those bounds, or without proposed_home_price, va_residual_income_guideline.status reads 'not_computable' with the reason instead. This block alone is a LOOKUP, not a verdict: it never compares against your actual residual income by itself. Optional.","type":["string","null"]},"property_tax_annual":{"default":null,"description":"Annual property tax in dollars. Optional; if omitted, estimated at 0.88% of the proposed home price. Must be zero or more.","type":["number","null"]},"proposed_debt":{"default":null,"description":"A proposed new debt, as an alternative to proposed_home_price. Provide at most one of proposed_debt or proposed_home_price; providing neither computes the current DTI only. Optional; a JSON null is treated as omitted, the same as leaving the field out.","properties":{"includes_tax_insurance":{"description":"Whether monthly_payment already includes tax and insurance. Optional, defaults to true when omitted; if false and type is 'mortgage', warns that lenders use full PITI for DTI.","type":["boolean","null"]},"monthly_payment":{"description":"Monthly payment in dollars. Required; must be positive.","type":["number","null"]},"name":{"description":"Optional label for this proposed debt.","type":["string","null"]},"type":{"description":"Debt type: 'auto', 'student', 'credit_card', 'personal', 'mortgage', 'heloc', 'child_support', or 'other'. Optional, defaults to 'mortgage' when omitted; an unrecognized value is rejected.","type":["string","null"]}},"type":["object","null"]},"proposed_down_payment_pct":{"default":null,"description":"Down payment as a percent of the proposed home price, e.g. 20 for 20%. Optional; defaults to 20 when omitted. Must be between 0 and 99.9 (100% cash purchases are not supported).","type":["number","null"]},"proposed_home_price":{"default":null,"description":"Proposed home purchase price in dollars. Provide at most one of proposed_debt or proposed_home_price; providing neither computes the current DTI only. Auto-calculates full PITI (principal, interest, taxes, insurance). Optional; must be at least $0.01, one cent, the smallest amount of money.","type":["number","null"]},"proposed_rate_pct":{"default":null,"description":"Proposed mortgage interest rate as a percent, e.g. 7.0 for 7.0%. Optional; the 7.0% default applies whenever this field is omitted, whether the proposal is proposed_debt or proposed_home_price. The default-rate warning fires only when proposed_home_price is used. Must be between 0 and 20.","type":["number","null"]},"proposed_term_years":{"default":null,"description":"Proposed mortgage term in years. Optional; defaults to 30 when omitted. Must be between 1 and 40.","type":["integer","null"]},"transaction_purpose":{"default":null,"description":"Mortgage transaction purpose: 'purchase', 'refinance', or 'streamlined_assist'. Optional, defaults to 'purchase' when omitted. Affects USDA only, and only what is disclosed. USDA's 32% PITI and 44% Total Debt figures are purchase-transaction waiver conditions (HB-1-3555 11.3.A.2), disclosed rather than applied as ceilings: Senaro cannot observe how the file is underwritten, so a USDA ratio overage is never 'ineligible' on any transaction purpose. For a refinance, 11.3.B states debt ratios 'are not limited to the maximum purchase debt ratio thresholds', so where the note fires it names both figures and states that neither applies. Streamlined-assist refinances require no debt ratio calculation at all. Conventional, FHA and VA are unaffected.","type":["string","null"]},"va_funding_fee_financed_monthly":{"default":null,"description":"The additional monthly payment from financing a VA funding fee into the loan balance, if any. 38 CFR 36.4313(e)'s applicable percentage depends on down payment, prior VA-loan use, and service category, none of which Senaro collects, so there is no default. If omitted while any VA figure that depends on it is produced, meaning qualification.va.your_back_end and its verdict, any what_if VA ratio, what_if.max_affordable_home.va, or qualification.va.residual_income_comparison, a VA_FUNDING_FEE_NOT_MODELED warning discloses that no fee is assumed. The home-price-reduction what_if scenario's hypothetical price is fixed before the fee is considered, so a supplied fee is scaled to that EXACT hypothetical loan size, since 38 CFR 36.4313(e)'s fee is a percentage of loan principal. what_if.max_affordable_home.va is a two-pass approximation instead, so its supplied fee is scaled to an ESTIMATE of the hypothetical loan size, not the exact figure reported; the PMI, tax, and insurance reservation itself is an EXACT closed-form solve, so only this fee-scaling step is approximate. Without proposed_home_price there is no reference loan size to scale from either way, so the raw fee is reserved unscaled instead, and a VA_FUNDING_FEE_NOT_SCALED warning discloses it. This is mutually exclusive with VA_FUNDING_FEE_NOT_MODELED by construction, since one requires the fee omitted and the other requires it supplied. Optional; must be zero or more.","type":["number","null"]}},"type":"object"}⟨77 unchanged words⟩ for the recurring 'save vs pay debt' question. Target months are clamped to [3, 12]: never below the 3-month personal-finance minimum, never above 12 (excess cash is better invested than parked).
{"properties":{"toolArgumentschart_title":{"default":null,"description":"JSONOverrideobjectforwiththethesechartparameterstitle. Must not contain em-dashes or en-dashes. Max 120 characters. Optional.","type":\n\nmonthly_essential_expenses["string","null"]},"current_savings":{"default":null,"description":"Whatdecimalyou>have0in(REQUIRED).liquidRent/mortgageemergency-accessible+savingsutilitiestoday.+Decimalfoodfrom+0insuranceto+$1,000,000,000.minimumOptional;debtdefaultspayments.toNOT0discretionarywhenspending.\ncurrent_savingsomitted.","type":["number","null"]},"dependents":{"default":null,"description":"Numberdecimalof>=dependents. Integer from 0(optionalto 20. +1 target month per dependent,defaultcapped at +3. Optional; defaults to 0).Whatwhenyouomitted.","type":["integer","null"]},"has_dual_income":{"default":null,"description":"Whenhavetrue,inpartnerliquidincomeemergency-accessiblereducessavingsthetoday.\njob_stability:buffer by 1 month. Optional; defaults to false when omitted.","type":["boolean","null"]},"job_stability":{"default":null,"description":"'stable_w2' | 'variable_income' | 'self_employed' |'between_jobs' (optional, default 'stable_w2').'between_jobs'. Drives the target-monthsmultiplier.\n stable_w2multiplier: stable_w2 salaried W-2 with consistent paycheck (+0 months).\n; variable_income:W-2 with commission/bonus/shift-based pay (+1 month).\n; self_employed:1099contractor / freelancer / solecontractor/freelancer/sole proprietor (+3 months).\n; between_jobs:actively job hunting, no current paycheck (+5 months).\ndependents: int >= 0 (optional, default 0).+1 target monthOptional;perdefaultsdependent,tocapped'stable_w2'atwhen+3.\nhas_dual_incomeomitted.","type":["string","null"]},"monthly_essential_expenses":{"description":"Rent/mortgagebool+(optional,utilitiesdefault+false).foodWhen+true,insurancepartner+incomeminimumreducesdebtthepayments.bufferNOTbydiscretionary1spending.month.\nmonthly_savings_capacity:Decimaldecimalfrom>=$0.010to(optional$1,000,000,000.defaultREQUIRED,0).no default.","type":"number"},"monthly_savings_capacity":{"default":null,"description":"What you can contribute toward the gap each month. Drivesmonths_to_target.\n\nTarget months are clamped tomonths_to_target.[3Decimal,12]:eithernever0beloworthefrom3-month$0.01personal-financetominimum$1,never above 12 (excess000,000,000.cashOptional;isdefaultsbettertoinvested0thanwhenparked).\nchart_titleomitted.","type":string (optional) override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters.["number","null"]}},"required":["toolArgumentsmonthly_essential_expenses"],"type":"object"}
{"properties":{"toolArgumentsannual_rate_pct":{"description":"JSONLoanobjectannualwithpercentagetheserate,parameters:\n\nprincipal:e.g.decimal6.5>not00.065.(REQUIRED)\nannual_rate_pct:Decimaldecimalfrom0-1000astopercentage100. REQUIRED,e.g.no6.5default.","type":"number"},"chart_bucket":{"default":null,"description":"Time-axisnotgranularity0.065of(REQUIRED)\nterm_monthsanalysis.buckets[]:int > 0'auto',(REQUIRED)\nloan_type:'monthly','personal''quarterly',|'yearly','auto'or|'biennial'.'student'Optional;|defaults'mortgage'to(optional'auto',defaultwhich'personal')\nextra_monthly_payment:selectsdecimalby>=term0length (optional,<=24defaultmonths:0)\nchart_bucketmonthly; <=60:'auto'quarterly;|<=360:'monthly'yearly;|else'quarterly'biennial).","type":["string","null"]},"chart_title":{"default":null,"description":"Override|for'yearly'the|chart'biennial'title.(optional,Mustdefaultnot'auto')\n Controlscontaintheem-dashestime-axisorgranularityen-dashes.ofMaxanalysis.buckets120 characters. Optional.","type":["string","null"].},"extra_monthly_payment":{"default":null,"description":"Extra'auto'principalselectspaidbasedeachonmonthtermbeyondlength:\n termthe<=regular24payment.monthsDecimal,->atmonthly;least<=0.60Optional;->defaultsquarterly;to<=0360when->omitted.","type":["number","null"]},"loan_type":{"default":null,"description":"'personal',yearly;'auto',>'student',360or->'mortgage'.biennial.\noutput:Optional;'summary'defaults|to'capture''personal'(optional,when omitted.","type":["string","null"]},"output":{"default":null,"description":"'summary' (default).or 'capture'. 'inline' is not a valid value for this tool on anytransport.\ntransport. 'summary':returns the full payload including analysis.buckets[]returnedinline.inline.\n'capture':writes the full payloadwrittento~/.senaro/captures/;~/.senaro/captures/capture_refandURIreturnsreturned;\n analysiscapture_ref,fieldstrippingstrippedanalysis fromwire response. Use when passing totheawirechartresponse;tool.\n Availableavailable on the local stdio transportonly;only, since the hosted HTTP transportrejects\n 'capture' with arejectsstructured'capture'errorandnamingnames 'summary' as the onlyvalid alternative.\nchart_titlealternative.","type":["string","null"]},"principal":{"description":"Loan(optional)principaloverridetoforamortize.theDecimal,chartgreatertitle.thanMust0.notREQUIRED,containnoem-dashesdefault.","type":"number"},"term_months":{"description":"Loanorterm.en-dashes.Integer,Maxgreater120thancharacters.0. REQUIRED, no default.","type":"integer"}},"required":["toolArgumentsprincipal","annual_rate_pct","term_months"],"type":"object"}
⟨18 unchanged words⟩ what that money would be worth if invested. Pick this when the input is recurring spending. Pick `compound_interest` when the input is a balance and its contributions with no spending to price, and `payoff_vs_invest` when the alternative to investing is paying down debt. The response includes `chart_hints` with rendering directives any ⟨13 unchanged words⟩
{"properties":{"toolArgumentsannual_return_pct":{"description":"JSONEffectiveobjectannualwithinvestmentthesereturn,parameters:\n\nmonthly_spending:e.g.decimal,8atnotleast0.08;0.01the monthly compounding step is (REQUIRED1+pct/100).^(1/12)-1.TheDecimalopportunityfromcost0oftospending100.$0REQUIRED,isnodegeneratedefault.","type":"number"},"chart_title":{"default":null,"description":"Overrideandforistherejected.\nannual_return_pct:chartdecimaltitle.0-100Mustasnotpercentagecontain em-dashes or en-dashes. Max 120 characters. Optional.","type":["string","null"]},"label":{"default":null,"description":"What the spending is, e.g.8'coffee'notor0.08'streaming subscriptions'. Optional.","type":["string","null"]},"monthly_spending":{"description":"MonthlyanspendingEFFECTIVEtoANNUALpricerate;againsttheinvesting.monthlyDecimal,compoundingatstepleastis$0.01.(1+pct/100)^(1/12)-1The(REQUIRED)\nyears:opportunityintcost>of0spending(REQUIRED)\nlabel:$0stringis(optional).degeneratee.g.and'coffee'isorrejected.'streamingREQUIRED,subscriptions'\ntax_bracket_pctno default.","type":"number"},"tax_bracket_pct":{"default":null,"description":"Taxdecimalbracket0-100as(optional)\nchart_title:astringpercentage,(optional)appliedoverrideasfora flat haircut to thechartinvestmenttitle.gain.MustDecimalnotfromcontain0em-dashestoor100.en-dashes.Optional.","type":["number","null"]},"years":{"description":"TimeMaxhorizon120incharacters.years. Integer, greater than 0. REQUIRED, no default.","type":"integer"}},"required":["toolArgumentsmonthly_spending","annual_return_pct","years"],"type":"object"}
{"properties":{"toolArgumentsannual_inflation_rate_pct":{"default":null,"description":"JSONAnnualobjectexpense-inflationwithrateparametersas a percentage. When greater than 0, expenses grow each month by the monthly equivalent of this annual rate; when 0, expenses are constant. Decimal, at least 0 and less than 100. Optional; defaults to 0 when omitted.","type":\n\nREQUIRED["number","null"]},"chart_title":\n current_savings{"default":null,"description":"Reserveddecimalfor>=the0.chart pipeline; validated but not yet used. Must not contain em-dashes or en-dashes. Max 120 characters. Optional.","type":["string","null"]},"current_savings":{"description":"Liquid fund available to draw down. Decimal from 0 to 1,000,000,000; 0 is valid (an already-empty fund).\n monthly_essential_expenses: decimal.>REQUIRED,0.no default.","type":"number"},"monthly_essential_expenses":{"description":"Monthly outflow at the chosen expensebasis.\n\nOPTIONAL:\n monthly_inflows:basis.decimalDecimal,>=greater than 0(defaultand0).at most 1,000,000,000. REQUIRED, no default.","type":"number"},"monthly_inflows":{"default":null,"description":"Ongoing monthly income that continues duringthe\nthe drawdown (partner income, side income, unemployment benefit, severance paid monthly).,Modeled\nmodeled as a flat monthly stream; a one-time severance lump and time-limited benefits are not modeled inv1.\n annual_inflation_rate_pct: decimal [0,v1.100)Decimal(defaultfrom 0).When >to01,expenses grow each month by the\n monthly-equivalent of this000,000,000.annualOptional;rate.defaultsWhento 0,expenses arewhenconstant.\n use_essential_expensesomitted.","type":bool (default true). true = essential-only basis (survival runway);\n false = total-spend basis (current-pace runway). Labels the reported expense_basis.\n chart_title["number","null"]},"output":string (optional). Reserved for the chart pipeline. Must not contain em-dashes or en-dashes. Max 120 characters.\n\nENVELOPE{"default":\n outputnull,"description":"'summary' (default)|, 'inline',|or'capture'\n summary:'capture'. 'summary' returns headline scalars (depletion month/or does-not-deplete)+andcitations;citations with the scheduleisstripped.stripped.\n inline:'inline' returns the full payload including the month-by-month schedule[](for chartrendering).\n capture:rendering. 'capture' writes the full payloadwrittento~/.senaro/captures/;~/.senaro/captures/capture_refandURIreturnsreturned.\n Availablecapture_ref; available on the local stdio transportonly;only, since the hosted HTTP transport rejects'capture'\n with a structured'capture'errorandnamingnames 'summary' and 'inline' as the valid alternatives.","type":["string","null"]},"use_essential_expenses":{"default":null,"description":"Expense basis: true means essential-only spending (survival runway), false means total spending (current-pace runway). Labels the reported expense_basis. Optional; defaults to true when omitted.","type":["boolean","null"]}},"required":["toolArgumentscurrent_savings","monthly_essential_expenses"],"type":"object"}
before
{"properties":{"toolArguments":{"description":"JSON object with these parameters:\n\ncards (REQUIRED array, max 20):\n - name: string (optional)\n - purchase_balance: decimal >= 0 (REQUIRED)\n - purchase_apr_pct: decimal 0-100 as percentage, e.g. 22.99 (REQUIRED)\n - cash_advance_balance: decimal >= 0 (optional, default 0)\n - cash_advance_apr_pct: decimal > 0, <= 100 (required if cash_advance_balance > 0)\n - minimum_payment: decimal >= 0 (optional, 0 = auto-calculate). Used as the locked floor for the constant keep-cards payment: each card pays max(your minimum, the bank minimum), held constant and rolled forward as cards clear.\n - segments: NOT SUPPORTED by this tool (rejected with a parse_error if supplied). This tool always reads the flat purchase_balance / cash_advance_balance fields above, never segments[] balances; supply those instead. segments[] input is supported by calculate_cc_payoff and compare_strategies.\n - monthly_spend / stop_spend_month: NOT SUPPORTED by this tool (rejected with a validation error if supplied). Ongoing spend on cards a consolidation loan or transfer just paid off is not modeled by any arm here; supported by calculate_cc_payoff and compare_strategies.\n\nconsolidation_loan (REQUIRED object):\n - annual_rate_pct: decimal 0-36 as percentage, e.g. 10.99 (REQUIRED)\n - term_months: int 12-84 (REQUIRED)\n - origination_fee_pct: decimal 0-10 (optional, default 0)\n - origination_fee_flat: decimal (optional, default 0, takes precedence if > pct-based fee)\n - include_fee_in_principal: bool (optional, default true)\n\nextra_monthly_payment: decimal >= 0 (optional, default 0)\ncurrent_strategy: 'avalanche' | 'snowball' (optional, default 'avalanche')\n(Note: fixed_payments is NOT a parameter of this tool, unlike calculate_cc_payoff. The keep-cards baseline is always simulated under the canonical constant rolled-forward payment, see comparison_basis in the response. Passing fixed_payments returns an unknown_parameter error.)\n\nBalance transfer, SINGLE OFFER (legacy, all optional):\ninclude_balance_transfer: bool (default false)\nbt_apr_pct: decimal 0-100 (required if include_balance_transfer: true, use 0 for 0% promo)\nbt_promo_months: int 1-60 (optional, default 18)\nbt_regular_apr_pct: decimal 0-100 (optional, default 25.20)\nbt_fee_pct: decimal 0-10 (optional, default 3.0)\n\nBalance transfer, MULTI-OFFER (preferred when comparing two or more offers):\nbt_offers: array of objects (max 10), when supplied, takes precedence over the scalar bt_* fields\n Each object:\n - apr_pct: decimal 0-100 (REQUIRED)\n - promo_months: int 1-60 (optional, default 18)\n - regular_apr_pct: decimal 0-100 (optional, default 25.20)\n - fee_pct: decimal 0-10 (optional, default 3.0)\n - label: string (optional, defaults to \"<apr_pct>% / <months>mo\")\nThe response includes a balance_transfer_offers block with per-offer simulation\nresults, selected_offer_index, selected_offer_label, selected_offer_reason, and all_offers_trap.\n\nPartial balance transfer (use when the BT offer has a transfer limit < your total debt):\nbt_transfer_limit: decimal >= 0.01 (optional), cap on total transferred amount.\n When set, only this amount moves to the BT card; remaining balances stay on original cards.\n A combined simulation runs both halves together, correctly redistributing freed minimum payments.\n When omitted, the entire balance is transferred (legacy behavior).\nbt_transfer_strategy: 'highest_apr_first' | 'highest_balance_first' | 'manual' (optional, default 'highest_apr_first')\n highest_apr_first: transfer from highest-APR segments first (maximizes interest savings)\n highest_balance_first: transfer largest balances first\n manual: use bt_manual_transfers to specify exact amounts per card\nbt_manual_transfers: array of objects (required when bt_transfer_strategy='manual')\n Each object:\n - card_name: string (must match a card name in cards[])\n - amount: decimal > 0\n\nfull_schedule: bool (optional, default false, compact schedule by default)\n\nwindfalls: array of one-time principal payments (optional, default empty, max 12). Same shape as calculate_cc_payoff. Each item:\n - month: int >= 0 (REQUIRED). 0 means applied before month 1's interest. N >= 1 applies at the END of calendar month N.\n - amount: decimal > 0 (REQUIRED).\n - label: string (optional). e.g. 'Tax refund', 'Year-end bonus'.\nWhen non-empty the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples.\n\nchart_title: string (optional) override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters.\n\nENVELOPE:\n output: 'summary' (default) | 'inline' | 'capture'\n summary: compact response with a data_preview block. No heavy array exists on this response today, so summary and inline are currently identical in content; the envelope is wired ahead of the future chart-render pipeline.\n inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering).\n capture: full payload written to ~/.senaro/captures/; capture_ref URI returned.\n Available on the local stdio transport only; the hosted HTTP transport rejects 'capture'\n with a structured error naming 'summary' and 'inline' as the valid alternatives."}},"required":["toolArguments"],"type":"object"}after
{"properties":{"bt_apr_pct":{"default":null,"description":"Balance-transfer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required when include_balance_transfer is true and bt_offers is omitted. bt_offers, when supplied, overrides this and the other three bt_* scalars below. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_fee_pct":{"default":null,"description":"Balance-transfer fee as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted. bt_offers, when supplied, overrides this. The 0-10 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_manual_transfers":{"default":null,"description":"Exact per-card transfer amounts. Required when bt_transfer_strategy is 'manual'; each entry's card_name must match a name in cards[]. Optional otherwise; a JSON null is treated as omitted, the same as leaving the field out.","items":{"properties":{"amount":{"description":"Dollar amount to transfer from this card, greater than $0, up to $1,000,000,000. Required per entry.","type":["number","null"]},"card_name":{"description":"Card name; must match a name in cards[]. Required per entry. Max 120 characters.","type":["string","null"]}},"type":["object","null"]},"type":["array","null"]},"bt_offers":{"default":null,"description":"Balance-transfer offers to compare head-to-head, 1 to 10, preferred over the four scalar bt_* fields above when comparing two or more offers: when supplied, bt_offers overrides bt_apr_pct, bt_promo_months, bt_regular_apr_pct, and bt_fee_pct, and their range checks are skipped. The response includes a balance_transfer_offers block with per-offer simulation results, selected_offer_index, selected_offer_label, selected_offer_reason, and all_offers_trap. Optional; a JSON null is rejected, unlike bt_manual_transfers and windfalls below, where a JSON null is treated as omitted.","items":{"properties":{"apr_pct":{"description":"Offer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required per offer.","type":["number","null"]},"fee_pct":{"description":"Balance-transfer fee for this offer, as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted.","type":["number","null"]},"label":{"description":"Label for this offer. Optional; defaults to '<apr_pct>% / <promo_months>mo' when omitted. Max 120 characters.","type":["string","null"]},"promo_months":{"description":"This offer's promo period in months, 1-60. Optional; defaults to 18 when omitted.","type":["integer","null"]},"regular_apr_pct":{"description":"APR that applies after this offer's promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted.","type":["number","null"]}},"type":["object","null"]},"type":["array","null"]},"bt_promo_months":{"default":null,"description":"Balance-transfer promo period in months, 1-60. Optional; defaults to 18 when omitted. bt_offers, when supplied, overrides this. The 1-60 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["integer","null"]},"bt_regular_apr_pct":{"default":null,"description":"APR that applies after the promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted. bt_offers, when supplied, overrides this. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_transfer_limit":{"default":null,"description":"Cap on the total dollar amount transferred to the balance-transfer card, at least $0.01. When set, only this amount moves to the BT card; remaining balances stay on original cards, and a combined simulation runs both halves together, correctly redistributing freed minimum payments. Optional; when omitted, the entire balance is transferred (legacy behavior). Needs include_balance_transfer or bt_offers.","type":["number","null"]},"bt_transfer_strategy":{"default":null,"description":"How to choose which balances move when bt_transfer_limit is less than your total debt: 'highest_apr_first' (transfer from highest-APR segments first, maximizes interest savings), 'highest_balance_first' (transfer largest balances first), or 'manual' (use bt_manual_transfers to specify exact amounts per card). Optional; defaults to 'highest_apr_first' when omitted. Needs bt_transfer_limit.","type":["string","null"]},"cards":{"description":"Credit cards to include, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards must be a JSON array.\"); the two are not the same rejection. segments and stop_spend_month are not supported by this tool and are rejected; a non-zero monthly_spend, annual_fee, or plan_fees_monthly is rejected too, but zero (including an explicit 0) is accepted and dropped for all three: this tool always reads the flat purchase_balance / cash_advance_balance fields on each card below, never segments[] balances, and card-level fees and ongoing spend are not modeled here. Those five fields are supported by calculate_cc_payoff and compare_strategies instead.","items":{"properties":{"cash_advance_apr_pct":{"description":"Cash advance APR as a percentage, greater than 0, up to 100. Required when cash_advance_balance is greater than 0.","type":["number","null"]},"cash_advance_balance":{"description":"Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted.","type":["number","null"]},"minimum_payment":{"description":"Minimum payment in dollars, $0 to $1,000,000,000. Optional; 0 or omitted auto-calculates the bank minimum. Used as the locked floor for the constant keep-cards payment: each card pays max(your minimum, the bank minimum), held constant and rolled forward as cards clear.","type":["number","null"]},"name":{"description":"Card label, e.g. 'Chase Sapphire'. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', ...). Max 120 characters.","type":["string","null"]},"purchase_apr_pct":{"description":"Purchase APR as a percentage, 0-100, e.g. 22.99. Required per card.","type":["number","null"]},"purchase_balance":{"description":"Purchase balance in dollars, $0 to $1,000,000,000. Required per card.","type":["number","null"]}},"type":"object"},"type":"array"},"chart_title":{"default":null,"description":"Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.","type":["string","null"]},"consolidation_loan":{"description":"Loan terms for the consolidation option. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"consolidation_loan must be an object.\"); the two are not the same rejection.","properties":{"annual_rate_pct":{"description":"Annual interest rate for the consolidation loan, as a percentage, 0-36, e.g. 10.99. Required.","type":["number","null"]},"include_fee_in_principal":{"description":"Whether the origination fee is rolled into the loan principal rather than paid upfront. Optional; defaults to true when omitted. A JSON null is rejected; omit the field instead of sending null.","type":["boolean","null"]},"origination_fee_flat":{"description":"Flat-dollar origination fee, $0 to $10,000. Optional; defaults to 0 when omitted, and takes precedence over origination_fee_pct when it produces a larger fee. A JSON null is rejected; omit the field instead of sending null.","type":["number","null"]},"origination_fee_pct":{"description":"Origination fee as a percentage of loan principal, 0-10. Optional; defaults to 0 when omitted. A JSON null is rejected, unlike every other optional field on this tool; omit the field instead of sending null.","type":["number","null"]},"term_months":{"description":"Consolidation loan term in months, 12-84. Required.","type":["integer","null"]}},"type":"object"},"current_strategy":{"default":null,"description":"Your current payoff strategy, compared against the consolidation loan / balance-transfer alternative: 'avalanche' or 'snowball'. Optional; defaults to 'avalanche' when omitted. Case-sensitive.","type":["string","null"]},"extra_monthly_payment":{"default":null,"description":"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums. Optional; defaults to 0 when omitted. fixed_payments is not a parameter of this tool, unlike calculate_cc_payoff: the keep-cards baseline is always simulated under the canonical constant rolled-forward payment (see comparison_basis in the response); supplying fixed_payments returns an unknown_parameter error.","type":["number","null"]},"full_schedule":{"default":null,"description":"Whether to return the full month-by-month amortization schedule instead of the compact default. Optional; defaults to false when omitted.","type":["boolean","null"]},"include_balance_transfer":{"default":null,"description":"Whether to run a single-offer balance-transfer scenario using the four scalar bt_* fields below. Optional; defaults to false when omitted. Ignored once bt_offers is supplied; use bt_offers when comparing two or more offers.","type":["boolean","null"]},"output":{"default":null,"description":"Response verbosity: 'summary' (default) | 'inline' | 'capture'. summary: compact response with a data_preview block; no heavy array exists on this response today, so summary and inline are currently identical in content. inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering). capture: full payload written to this server's local disk for the chart-render pipeline; capture_ref URI returned. Available on the local stdio transport only; the hosted HTTP transport rejects 'capture' with a structured error naming 'summary' and 'inline' as the valid alternatives. Optional; defaults to 'summary' when omitted.","type":["string","null"]},"windfalls":{"default":null,"description":"One-time principal payments, at most 12, same shape as calculate_cc_payoff. Optional; a JSON null is treated as omitted, the same as leaving the field out. When non-empty, the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples.","items":{"properties":{"amount":{"description":"Dollar amount of the windfall, greater than 0. Required per entry.","type":["number","null"]},"label":{"description":"Optional label for this windfall, e.g. 'Tax refund' or 'Year-end bonus'. Max 120 characters.","type":["string","null"]},"month":{"description":"Month index the windfall is applied, 0 or more. 0 means applied before month 1's interest; N >= 1 applies at the end of calendar month N. Required per entry.","type":["integer","null"]}},"type":["object","null"]},"type":["array","null"]}},"required":["cards","consolidation_loan"],"type":"object"}{"properties":{"toolArgumentsclosing_cost_pct":{"default":null,"description":"JSON objectClosingwithcoststheseasparameters:\n\nhome_price:adecimalpercentage>of0,the<=loan1,000amount,0000-20,000(REQUIRED)\ndown_payment_pct:pointsdecimalexcluded.0-100Optional;asdefaultspercentageto(optional,thedefaultUrban20)\ndown_payment_amount:Institutedecimalloan-size>=regressive0schedule (optional;aboutoverrides4.6%down_payment_pctatifaprovided)\n\noption_a$97K(REQUIREDloanobject):\n -downlabel:tostringabout(optional;1.4%auto-generatedatifaomitted$679K loan)\n -annual_rate_pct:whendecimalomitted.0-20Passas0percentage,toe.g.model6.25zero(REQUIRED)\n -closingterm_yearscosts.","type":["number","null"]},"down_payment_amount":{"default":null,"description":"Downintpayment1-40in(REQUIRED)\n -dollars.is_arm:Optional;booloverrides(optionaldown_payment_pct entirely,defaultincludingfalse;itsARMprovenancenotrow,yetwhensupported)\n -supplied.points:Mustdecimalbe0-4at(optional,leastdefault$00;anddiscountstrictlypointsbelowboughthome_price.","type":["number","null"]},"down_payment_pct":{"default":null,"description":"Downeachpayment=as1%aofpercentloan)\n -ofpoints_rate_reduction_pct:home_price,decimale.g.0-1.0,20PERCENTAGEforPOINTS20%.reductionOptional;perdefaultspointto(optional,20defaultwhen0.25)\n\noption_bomitted.(REQUIREDRangeobject):\n -0-100sameappliesshapeonlyaswhenoption_a\n -down_payment_amountMustisdifferabsent;fromwhenoption_adown_payment_amountonisatsupplied,leastdown_payment_pctoneisof:ignoredterm_yearsentirely,annual_rate_pct,includingorinpoints\n\nproperty_tax_annualprovenance.","type":["number","null"]},"extra_monthly_payment":{"default":null,"description":"Extradecimalprincipal>=payment0in(optionaldollars,defaultapplied0;equallyfortotrueBOTHmonthlyoptionscost)\nhome_insurance_annual:everydecimalmonth.>=Optional; defaults to 0(optional,whendefaultomitted.0)\npmi_monthly:Mustdecimalbe>=zero0,or<=more1and no more than $1,000,000,000 (optional000.","type":["number","null"]},"filing_status":{"default":null,"description":"Tax0;filingPMIstatus:if'single',<'married',20%ordown)\npmi_removal_ltv_pct:'head_of_household'.decimalOptional;50-100matched(optional).case-insensitively.","type":["string","null"]},"full_schedule":{"default":null,"description":"WhetherWhentoomitted,returnPMItheisfullmodeledmonth-by-monthasamortizationremovedscheduleatinstead of the78%compactHPAdefault.automatic-terminationOptional;threshold.defaultsProvidetoafalsevaluewhen(e.g.omitted.","type":["boolean","null"]},"hoa_monthly":{"default":null,"description":"Monthly80)homeownerstoassociationmodelduesborrower-requestedinremovaldollars.atOptional;thatdefaultsLTVto(whichever0ofwhen78%omitted.orMustyourbevaluezeroisorreachedmorefirst).andEithernowaymorePMIthanalso$1,000,000,000.","type":["number","null"]},"home_insurance_annual":{"default":null,"description":"Annualstopshomeatinsurancetheinstatutorydollars.amortizationOptional;midpointdefaultsoftoeach0option'swhenownomitted.termMust(12beU.S.C.zero§4901(7),or§4902(c))more.","type":["number","null"]},"home_price":{"description":"Homewhichpurchasethispricevalueincannotdollars.postpone.\nhoa_monthly:Required.decimalMust>=be0positive(optional,anddefaultno0)\n\ninvest_the_difference:moreboolthan(optional$1,000,000,000.","type":"number"},"invest_the_difference":{"defaulttrue). When true":null,"description":"Whether both options deploy the same total budget every ⟨52 unchanged words⟩ budget goes to investments. See comparison_basis in theresponse.\ninvestment_return_pctresponse. Optional; defaults to true when omitted.","type":["boolean","null"]},"investment_return_pct":{"default":null,"description":"Assumeddecimalinvestment0-30return on the invested payment gap, as a percentage, an EFFECTIVE ANNUAL rate; the monthly compounding step is (1+pct/100)^(1/12)-1-1.(optional;Optional; defaults to the cited Senaro long-run S&P 500 nominal return, about 10%)\ntax_bracket_pct, when omitted. Range 0-30.","type":["number","null"]},"option_a":{"description":"Thedecimalfirst0-50fixed-rate mortgage option to compare. Required.","properties":{"annual_rate_pct":{"description":"Annual interest rate for this option, as a percentage,(optional;0-20,enablese.g.after-tax6.25.investmentRequired.","type":["number","null"]},"is_arm":{"description":"Whetherreturnthisandoptionmortgageisinterestandeductionadjustable-rateanalysis;mortgage.theOptional;after-taxdefaultscomparisontocreditsfalse when omitted. ARM analysis is not yet supported: true on either option is rejected.","type":["boolean","null"]},"label":{"description":"Display label for this option, e.g. '30-year fixed'. Optional; auto-generated when omitted. At most 120 characters.","type":["string","null"]},"points":{"description":"Discount points bought, eachoption'sequalannualtodeduction1%savingsof the loan amount, 0-4. Optional; defaults toits0investmentswhenatomitted.","type":["number","null"]},"points_rate_reduction_pct":{"description":"Interest-rateyearreductionend)\nstandard_deductionper discount point, in percentage points, 0-1.0. Optional; defaults to 0.25 when omitted.","type":["number","null"]},"term_years":{"description":"Mortgagedecimalterm(optional.inDefaultsyears, 1-40. Required.","type":["integer","null"]}},"type":"object"},"option_b":{"description":"The second fixed-rate mortgage option tothecompare,IRSsamebasicshapestandardasdeductionoption_a. Required. Must differ from option_a on at least one of term_years, annual_rate_pct, or points.","properties":{"annual_rate_pct":{"description":"Annual interest rate fortax_yearthis+option,filing_status.asTY2026a percentage, 0-20, e.g. 6.25. Required.","type":["number","null"]},"is_arm":{"description":"Whether16100thissingleoption is an adjustable-rate mortgage. Optional; defaults to false when omitted. ARM analysis is not yet supported: true on either option is rejected.","type":["boolean","null"]},"label":{"description":"Display32200labelmarriedfor this option,24150e.g.head_of_household.'30-yearTY2025fixed'. Optional; auto-generated when omitted. At most 120 characters.","type":["string","null"]},"points":{"description":"Discount15750pointssinglebought,31500eachmarriedequal to 1% of the loan amount,236250-4.head_of_household.Optional;Sourcedefaults to 0 when omitted.","type":["number","null"]},"points_rate_reduction_pct":{"description":"Interest-rateRev.reductionProc.per2025-32)\nfiling_statusdiscount point, in percentage points, 0-1.0. Optional; defaults to 0.25 when omitted.","type":["number","null"]},"term_years":{"description":"Mortgage'single'term|in'married'years,|1-40.'head_of_household'Required.","type":["integer","null"]}},"type":"object"},"pmi_monthly":{"default":null,"description":"Monthly PMI (optionalprivate mortgage insurance)\ntax_yearin dollars, charged when down payment is below 20%. Optional; defaults to 0 when omitted. Must be zero or more and no more than $1,000,000,000.","type":["number","null"]},"pmi_removal_ltv_pct":{"default":null,"description":"Loan-to-valueintpercentage at which to model borrower-requested PMI removal,202550-100. Optional; when omitted, PMI is modeled as removed at the 78% HPA automatic-termination threshold instead. When the loan's own initial loan-to-value is above 80 percent, the range where PMI applies, a value at or2026above(optionalthat initial LTV is rejected,defaultbecause2026;theselectsrequested removal point would already be met at theIRSfirststandard-deductionpayment,tableso no PMI would be modeled for any month of theitemize-vs-standardloan.analysisAt or below 80 percent, no such check runs. Either way PMI also stops at the statutory amortization midpoint of each option's own term (12 U.S.C. §4901(7)\n\nextra_monthly_payment, §4902(c)), which this value cannot postpone.","type":["number","null"]},"property_tax_annual":{"default":null,"description":"Annualdecimalproperty>=tax0in dollars,<=for1true monthly cost. Optional; defaults to 0 when omitted. Must be zero or more.",000"type":["number",000"null"]},000"standard_deduction":{"default":null,"description":"Standard(optionaldeduction in dollars,defaultcompared0;againstextraitemizedprincipalmortgage-interestapplieddeductions.equallyOptional; defaults toBOTHtheoptions)\ntime_horizon_years:IRSintbasic1-40standard(optional;deductiondefaultfor tax_year and filing_status when omitted (TY2026:max16100ofsingle,both32200term_years)\nfull_schedulemarried, 24150 head_of_household; TY2025:bool15750(optionalsingle,default31500false;married,compact23625amortizationhead_of_household;bysourcedefaultRev. Proc. 2025-32)\nclosing_cost_pct. Must be zero or more.","type":["number","null"]},"tax_bracket_pct":{"default":null,"description":"Marginaldecimaltax0-20bracket as a percentage,of0-50.loanOptional;amountenables(optional,after-tax investment return and mortgage interest deduction analysis when supplied. The after-tax comparison credits each option's annual deduction savings to its investments at year end.","type":["number","null"]},"tax_year":{"default":null,"description":"TaxUrbanyear,Institute2025loan-sizeorregressive2026,scheduleselecting(~4.6%theatIRS$97Kstandard-deductionloantabledownfor the itemize-vs-standard analysis. Optional; defaults to~1.4%2026atwhen$679K)omitted.","type":["integer","null"]},"time_horizon_years":{"default":null,"description":"Numberpointsofexcluded.yearsPassto0project the invest-the-difference comparison, 1-40. Optional; defaults tomodelthezeromaximumclosingofcosts)both options' term_years when omitted.","type":["integer","null"]}},"required":["toolArgumentshome_price","option_a","option_b"],"type":"object"}
⟨349 unchanged words⟩ MCP server renders them locally over stdio only.Useoutput:'summary''capture'(default)isforavailableaoncompacttheresponselocalorstdio'inline'transportforonly,theandfullispayload.rejectedoutput:with'capture'awritesstructured error on thefullhostedpayloadHTTPtotransport,awherefileaoncapture_refthiswouldserver'sbelocaladiskdeadandlinkreturnsfor acapture_refremoteURIcaller;forseecharttherendering;outputavailableparameteronfor thelocalresponsestdioverbositytransportmodes.only,Thisandtoolrejectedtakeswithnoastrategy,structuredfixed_payments,errorfull_scheduleonortheper_segmenthostedparameter:HTTPittransport,alwayswherecomparesaavalanchecapture_refagainstwouldsnowballbeoverathedeadfulllinkschedule,forsoaallremotefourcaller.are rejected as unknown_parameter.
before
{"properties":{"toolArguments":{"description":"JSON object with these parameters:\n\ncards (REQUIRED array, max 20): same format as calculate_cc_payoff\n - name, purchase_balance, purchase_apr_pct (REQUIRED)\n - cash_advance_balance, cash_advance_apr_pct (optional)\n - minimum_payment (OPTIONAL, omit or 0 to auto-calculate)\n - annual_fee: decimal >= 0 (optional, default 0). Charged at month 1 and every 12th month thereafter.\n - plan_fees_monthly: decimal >= 0 (optional, default 0). Charged every month while the card has a balance.\n - segments: array (OPTIONAL; when present, supersedes purchase_balance / cash_advance_balance). Max 100 segments total across all cards in the request. Per-card, per-type caps: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan. Same per-segment shape as calculate_cc_payoff; see that tool's segments[] documentation for the full field list.\n\nextra_monthly_payment: decimal >= 0 (optional, default 0)\n(Note: fixed_payments is NOT a parameter of this tool, unlike calculate_cc_payoff. Avalanche and snowball are always compared under the canonical constant rolled-forward payment, see comparison_basis in the response. Passing fixed_payments returns an unknown_parameter error.)\napply_rate_cap: bool (optional, default false)\nchart_title: string (optional) override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters.\noutput: 'summary' | 'inline' | 'capture' (optional, default 'summary')\n 'capture' is available on the local stdio transport only; the hosted HTTP transport rejects it with a structured error naming 'summary' and 'inline' as the valid alternatives."}},"required":["toolArguments"],"type":"object"}after
{"properties":{"apply_rate_cap":{"default":null,"description":"Whether to cap each card's APR at the regulatory ceiling before simulating. Optional; defaults to false when omitted.","type":["boolean","null"]},"cards":{"description":"Credit cards to compare, 1 to 20, the same shape calculate_cc_payoff takes. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards is required and must be an array.\"); the two are not the same rejection. Every card may carry segments[]. Max 100 segments total across all cards in the request. Per-card, per-type caps: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan.","items":{"properties":{"annual_fee":{"description":"Annual fee in dollars, $0 to $1,000,000,000. Optional; defaults to 0. Charged at month 1 and every twelfth month after, while the card carries a balance.","type":["number","null"]},"cash_advance_apr_pct":{"description":"Cash advance APR as a percentage, greater than 0 and up to 100. Required when cash_advance_balance is greater than 0: cash advances have no promotional 0% product, so a 0% rate on a real advance balance is a data-entry error.","type":["number","null"]},"cash_advance_balance":{"description":"Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted. A POSITIVE value alongside a non-empty segments[] is rejected, the same way purchase_balance is. An explicit 0 is accepted.","type":["number","null"]},"minimum_payment":{"description":"Minimum payment in dollars, $0 to $1,000,000,000 (optional, omit or set 0 to auto-calculate). Where it binds, the card is locked at max(minimum_payment, that card's issuer minimum computed at month 1), and that locked amount is paid every month. On calculate_cc_payoff it binds ONLY when fixed_payments = true; on the DEFAULT path (fixed_payments = false) it is NOT used, because the plan recomputes each card's issuer minimum from its current balance every month, and the response discloses that as MINIMUM_PAYMENT_NOT_BINDING. On compare_strategies there is no fixed_payments parameter and supplying one is rejected: the avalanche and snowball arms ALWAYS run locked, so the value DOES bind and moves both arms, while the minimum-payments-only baseline always recomputes and ignores it, disclosed as MINIMUM_PAYMENT_NOT_BINDING_IN_BASELINE.","type":["number","null"]},"monthly_spend":{"description":"Recurring monthly purchase amount charged to this card's purchase balance before interest accrues, $0 to $50,000 per month. Optional; defaults to 0. Use the segment-level monthly_spend instead when supplying segments[].","type":["number","null"]},"name":{"description":"Card label, e.g. 'Chase Sapphire', 120 characters or fewer. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', and so on). Echoed into per-card results and warning text. A name over the cap is replaced in error field paths by a key built from its zero-based card index, written as '#0 (name over cap)', '#1 (name over cap)' and so on.","type":["string","null"]},"plan_fees_monthly":{"description":"Recurring monthly card fee in dollars, $0 to $1,000,000,000, e.g. a pay-over-time plan fee. Optional; defaults to 0. Charged every month while the card carries a balance.","type":["number","null"]},"purchase_apr_pct":{"description":"Purchase APR as a percentage, 0 to 100, e.g. 24.99 not 0.2499. Required when purchase_balance is greater than 0: an omitted APR would silently compute $0 interest.","type":["number","null"]},"purchase_balance":{"description":"Purchase balance in dollars, $0 to $1,000,000,000. Required unless segments[] carries at least one segment: an omitted purchase_balance would silently report a $0, 0-month payoff. Supplying a POSITIVE value alongside a non-empty segments[] is rejected, since the two would be competing sources for the same balance. An explicit 0 is accepted.","type":["number","null"]},"segments":{"description":"Per-segment breakdown of this card's balances. Optional; when it carries at least one segment it SUPERSEDES purchase_balance and cash_advance_balance, and a POSITIVE value in either of those is rejected. An empty segments[] is treated as absent, so purchase_balance is then required. At most 100 segments across the whole request. Per card, per type: 1 purchase, 1 cash_advance, 5 balance_transfer, 1 promotional, 10 installment_plan. Each item carries its own type, balance, rate and payment priority; see the type field on the item for the per-type field matrix.","items":{"properties":{"apr_pct":{"default":null,"description":"Annual percentage rate for this segment, 0 to 100, e.g. 24.99 not 0.2499. Required when balance is greater than 0 on purchase, cash_advance, balance_transfer and promotional. On cash_advance it must be greater than 0 whenever a balance is carried. Must be 0 on installment_plan, which uses monthly_fee instead, so omitting it there is the correct shape.","type":["number","null"]},"balance":{"description":"Segment balance in dollars, $0 to $1,000,000,000. REQUIRED on every segment type: an omitted balance would silently report a $0, 0-month payoff, so it is rejected instead. An explicit 0 is valid, for example a paid-off balance_transfer segment kept for schedule continuity.","type":"number"},"extra_payment_order":{"default":null,"description":"Extra-payment tie-break priority, 0 or more, where 0 means this segment never receives extra payment. Optional on every type, and the default for installment_plan. Only breaks a tie between segments sharing the exact same current APR, since the Credit CARD Act (TILA §164(b), 15 U.S.C. §1666c(b)) / 12 CFR 1026.53(a) always pays the highest-current-APR segment first regardless of this value.","type":["integer","null"]},"merchant_name":{"default":null,"description":"Label for an installment plan's merchant, 120 characters or fewer. Optional on installment_plan, ignored on every other type.","type":["string","null"]},"min_payment_order":{"default":null,"description":"Minimum-payment tie-break priority, 1 or more. Optional on every type. The minimum first pays any installment_plan's locked plan_payment_due in full, then the lowest-current-APR segment; this value only breaks a tie between segments sharing both the same current APR and the same installment-plan status.","type":["integer","null"]},"monthly_fee":{"default":null,"description":"Fixed fee charged each month while an installment plan's term is active, $0 or more and no greater than plan_payment_due. Optional on installment_plan. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"monthly_spend":{"default":null,"description":"Recurring monthly purchase amount posted to this segment before interest accrues, $0 to $50,000 per month. Optional on purchase. A negative value is rejected as NEGATIVE_BALANCE on every type. On every type other than purchase a positive value is rejected with FIELD_NOT_ALLOWED_HERE, since those balances do not accept new purchases; an explicit 0 is accepted.","type":["number","null"]},"plan_payment_due":{"default":null,"description":"Locked monthly payment for an installment plan, principal plus monthly_fee. Required on installment_plan, greater than $0, at least monthly_fee, and no more than $1,000,000,000. On every other type a positive value is rejected with FIELD_NOT_ALLOWED_HERE, while 0 and a negative value are accepted and dropped.","type":["number","null"]},"promo_expires_month":{"default":null,"description":"Month at which apr_pct flips to revert_apr_pct, 1 to 480. Required on balance_transfer and promotional. Ignored on purchase, cash_advance and installment_plan.","type":["integer","null"]},"remaining_payments":{"default":null,"description":"Payments left in an installment plan's stated term, 0 or more. Optional on installment_plan, ignored on every other type. 0 means the term has ALREADY ended and is valid with any balance, including a positive residual. From 1 up, the balance must be clearable within the stated term and must not be clearable a month early.","type":["integer","null"]},"revert_apr_pct":{"default":null,"description":"Rate this segment reverts to once its promo expires, 0 to 100, and at least apr_pct. Required on balance_transfer and promotional. Ignored on purchase and cash_advance. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate rather than repricing.","type":["number","null"]},"stop_spend_month":{"default":null,"description":"Month index at which recurring spend stops, 0 or more. Read on purchase only, and range checked on every type. Omit to spend for the whole projection.","type":["integer","null"]},"type":{"description":"Segment type. REQUIRED on every segment: omitting it is rejected. Per-type field matrix. Every field below is classified for every segment type: REQUIRED (omitting it is rejected), OPTIONAL (accepted either way and read), IGNORED (accepted and never read for this type, though a value can still fail the field's own range check), or REJECTED (supplying a disallowed value is an error; the field's own rule below says exactly which values are disallowed). Value rules are stated separately from applicability, because a field can be accepted on a type and still be restricted there. The validators are the authority; this matrix describes them.\n- type: REQUIRED on every type. Values: one of purchase, cash_advance, balance_transfer, promotional, installment_plan.\n- balance: REQUIRED on every type. Values: $0 to $1,000,000,000; above $50,000 returns a HIGH_CARD_BALANCE warning, not an error.\n- apr_pct: REQUIRED on purchase, cash_advance, balance_transfer, promotional; OPTIONAL on installment_plan. Values: 0 to 100 as a percentage, e.g. 24.99 not 0.2499. The REQUIRED classification above applies when balance is greater than 0; a zero-balance segment may omit it. Must be greater than 0 on cash_advance carrying a balance. Must equal 0 on installment_plan, where omitting it is the correct shape.\n- revert_apr_pct: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance; REJECTED on installment_plan. Values: 0 to 100, and at least apr_pct. Rejected on installment_plan with FIELD_NOT_ALLOWED_HERE: an expired plan's residual keeps its existing rate.\n- promo_expires_month: REQUIRED on balance_transfer, promotional; IGNORED on purchase, cash_advance, installment_plan. Values: 1 to 480.\n- monthly_fee: OPTIONAL on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: $0 or more, and no greater than plan_payment_due, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- plan_payment_due: REQUIRED on installment_plan; REJECTED on purchase, cash_advance, balance_transfer, promotional. Values: greater than $0, at least monthly_fee, and no more than $1,000,000,000, on installment_plan. On every other type a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; 0 and a negative value are accepted and dropped there.\n- remaining_payments: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 0 or more. 0 means the stated term has ALREADY ended and is valid with any balance. From 1 up, balance must be clearable within the stated term.\n- min_payment_order: OPTIONAL on every type. Values: 1 or more; breaks a tie only between segments sharing both the same current APR and the same installment-plan status.\n- extra_payment_order: OPTIONAL on every type. Values: 0 or more; 0 means skip. Breaks a tie only between segments sharing the exact same current APR.\n- merchant_name: OPTIONAL on installment_plan; IGNORED on purchase, cash_advance, balance_transfer, promotional. Values: 120 characters or fewer.\n- monthly_spend: OPTIONAL on purchase; REJECTED on cash_advance, balance_transfer, promotional, installment_plan. Values: $0 to $50,000 per month. A negative value is rejected as NEGATIVE_BALANCE on every type, purchase included. On every type other than purchase a POSITIVE value is rejected with FIELD_NOT_ALLOWED_HERE; an explicit 0 is accepted.\n- stop_spend_month: OPTIONAL on purchase; IGNORED on cash_advance, balance_transfer, promotional, installment_plan. Values: 0 or more; range checked on every type, read only on purchase.","type":"string"}},"required":["type","balance"],"type":"object"},"type":["array","null"]},"stop_spend_month":{"description":"Month index at which this card's recurring spend stops, 0 or more. Optional; omit to spend for the whole projection.","type":["integer","null"]}},"type":"object"},"type":"array"},"chart_title":{"default":null,"description":"Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.","type":["string","null"]},"extra_monthly_payment":{"default":null,"description":"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums. Optional; defaults to 0 when omitted.","type":["number","null"]},"output":{"default":null,"description":"Response verbosity: 'summary' (default) | 'inline' | 'capture'. summary returns the headline comparison with a data_preview block; inline returns the full payload; capture writes the full payload to this server's local disk for the chart-render pipeline and returns a capture_ref URI. capture is available on the local stdio transport only, and the hosted HTTP transport rejects it with a structured error naming 'summary' and 'inline' as the valid alternatives, since a capture_ref would be a dead link for a remote caller. Optional; defaults to 'summary' when omitted.","type":["string","null"]}},"required":["cards"],"type":"object"}⟨18 unchanged words⟩ interest earned, effective annual rate, and milestones. Pick this for a balance that grows with contributions. Pick `calculate_opportunity_cost` when the money is recurring spending being priced against investing, and `calculate_loan_payoff` when the balance amortizes down under a fixed payment. The response includes `chart_hints` with rendering directives any ⟨13 unchanged words⟩
{"properties":{"toolArgumentsannual_rate_pct":{"description":"JSONAnnualobjectinterestwithratetheseasparameters:\n\nprincipal:adecimalpercentage,>=e.g. 7 not 0.07. Decimal from 0(to 100. REQUIRED)\nannual_rate_pct, no default.","type":"number"},"apply_default_inflation":{"default":null,"description":"Whendecimaltrue0-100andasinflation_rate_pctpercentage,ise.g.0,7auto-selectsnotinflation0.07via(REQUIRED)\nyears:MacroeconomicDefaults.ForHorizon.intIgnored>=when1inflation_rate_pct(REQUIRED)\nmonthly_contribution:isdecimalgreater>=than 0(optional,ordefaultrate_convention0)\ncompounds_per_year:isint'real'.>Optional;0defaults(optional,to false when omitted.","type":["boolean","null"]},"chart_title":{"default":null,"description":"Override12)\ninflation_rate_pctfor the chart title. Must not contain em-dashes or en-dashes. Max 120 characters. Optional.","type":["string","null"]},"compounds_per_year":{"default":null,"description":"Compoundingdecimalperiods>=per0year.(optionalInteger,defaultgreater0than=0.NOOptional;real-valuedefaultsoverlay;to>012=whenexplicitomitted.","type":["integer","null"]},"inflation_rate_pct":{"default":null,"description":"Inflationpercentageratee.g.as3.5;a-1percentage.=Decimal: -1 (deprecated suppress, same as 0)\napply_default_inflation:,bool0 (optionalno real-value overlay),defaultorfalse;greaterwhenthantrue0 andinflation_rate_pct=0less than 100 (explicit percentage,auto-selectse.g.inflation3.5).viaOptional;MacroeconomicDefaults.ForHorizon;defaultsignoredto 0 wheninflation_rate_pct>0omitted.","type":["number","null"]},"monthly_contribution":{"default":null,"description":"Additionalorcontributionrate_convention='real')\nrate_conventionadded each month. Decimal, at least 0. Optional; defaults to 0 when omitted.","type":["number","null"]},"principal":{"description":"Starting'nominal'|'real'balance.(optionalDecimal, at least 0. REQUIRED, no default.","type":"number"},"rate_convention":{"default":null,"description":"'nominal''nominal';or 'real'. 'real' unconditionally suppresses the inflation overlay; use when annual_rate_pct is alreadyinflation-adjusted)\nchart_title:inflation-adjusted.stringOptional;(optional)defaultsoverridetofor'nominal'thewhenchartomitted.","type":["string","null"]},"years":{"description":"Timetitle.horizonMustinnotyears.containInteger,em-dashesatorleasten-dashes.1.MaxREQUIRED,120nocharacters.default.","type":"integer"}},"required":["toolArgumentsprincipal","annual_rate_pct","years"],"type":"object"}
{"properties":{"toolArgumentsannual_salary":{"description":"JSONAnnualobjectgrosswithsalary.parametersDecimal > 0. REQUIRED, no default.","type":\n\nREQUIRED"number"},"chart_title":\n annual_salary{"default":null,"description":"Overridedecimalfor>the0.chartAnnualtitle.grossReservedsalary.\n pay_periods_per_year:forintegertheinchart[1,pipeline.365].MustPaynotperiodscontainperem-dashesyearor(12=monthly,en-dashes.24=semi-monthly,Max26=biweekly,12052=weekly).\ncharacters. Optional.","type":["string","null"]},"contribution_pct":{"description":"Currentdecimalemployee contribution as a percent of gross pay. Decimal in [0, 100].CurrentREQUIRED,employeenocontributiondefault.","type":"number"},"has_true_up":{"default":null,"description":"Whetherastheaplanpercentprovidesofangrossannualpay.\n\nMATCHtrue-up.FORMULAfalse(exactlyisonetherequired)conservative assumption:\nsurfaces front-loading forfeiture risk. Optional; defaults to false when omitted.","type":["boolean","null"]},"match_preset":{"default":null,"description":"Namedonematch-formulaofpreset: 'safe_harbor_basic' (100% of first 3% + 50% of next 2%),'safe_harbor_enhanced_simple'\n'safe_harbor_enhanced_simple' (100% of first 4%), 'qaca' (100% ⟨7 unchanged words⟩ 5%), 'fifty_pct_of_first_six_pct' (50% of first 6%).\n match_tiers:.arrayExactlyofonetierofobjectsmatch_preset[{ormatch_frac:match_tiersdecimalis(0,1],required.up_to_deferral_pct:Optional;decimalomit>when0supplying}match_tiers.",..."type":["string","null"].\n match_frac is the employer fraction (0.5 = 50%). up_to_deferral_pct is},"match_tiers":{"default":null,"description":"Customthematch-formula tierwidth as a percent oflist.pay.\nExample: [{match_frac\"match_frac\": 1.0,up_to_deferral_pct\"up_to_deferral_pct\": 3}, {match_frac\"match_frac\": 0.5,up_to_deferral_pct\"up_to_deferral_pct\": 2}] =safe_harbor_basic.\n\nOPTIONAL:\n has_true_up: boolsafe_harbor_basic.(defaultExactlyfalse).oneWhetherofthematch_presetplanorprovidesmatch_tiersanisannualrequired.true-up.\n falseOptional;isomitthewhenconservativesupplyingassumptionmatch_preset.","items":{"properties":{"match_frac":{"description":"Employersurfacesmatchfront-loadingfractionforfeitureforrisk.\n participant_age:thisintegertier>=(0.50=(optional50%).Determines which catch-upMustlimitbeappliesin (age 50+0,or age1].","type":["number","null"]},"up_to_deferral_pct":{"description":"Width60-63ofSECUREthis2.0tiersuperascatch-up).\n Omitawhenpercentageofispayunknown(e.g.or3participant=istheunderfirst50.\n chart_title:3%stringof(optionalpay).Reserved for the chart pipeline.Mustnot contain em-dashes or en-dashes. Maxbe120>characters.\n\nENVELOPE0.","type":\n["number","null"]}},"type":["object","null"]},"type":["array","null"]},"output":{"default":null,"description":"Response envelope. 'summary' (default)| 'inline' | 'capture'\n summary: headline scalars(match captured/forfeited,full-match threshold, front-load flag, applied_caps, citations);\n the per-periodperiod_scheduleisstripped.stripped.\n inline'inline': full payload includingtheperiod_schedule[](for chart.rendering).\n capture'capture': full payload written to~/.senaro/captures/;~/.senaro/captures/, capture_ref URIreturned.\n Available on thereturned; local stdio transportonly; the hosted HTTP transportonly,rejectsrejected'capture'\nwith a structured error on the hosted HTTP transport naming 'summary' and 'inline' as the valid alternatives.","type":["string","null"]},"participant_age":{"default":null,"description":"Determines which catch-up limit applies (age 50+, or age 60-63 SECURE 2.0 super catch-up). Integer >= 0. Optional; omit when age is unknown or participant is under 50.","type":["integer","null"]},"pay_periods_per_year":{"description":"Pay periods per year (12=monthly, 24=semi-monthly, 26=biweekly, 52=weekly). Integer in [1, 365]. REQUIRED, no default.","type":"integer"}},"required":["toolArgumentsannual_salary","pay_periods_per_year","contribution_pct"],"type":"object"}
{"properties":{"toolArgumentschart_title":{"default":null,"description":"JSONOverrideobjectforwiththethesechartparameterstitle. Must not contain em-dashes or en-dashes. Max 120 characters. Optional.","type":\n\ndebt_type["string","null"]},"debt_apr_pct":{"description":"Debt'credit_card'annual|percentage'auto'rate,|e.g.'student'6.5|not'personal'0.065.|Decimal'mortgage'from(0 to 100. REQUIRED)\ndebt_balance, no default.","type":"number"},"debt_balance":{"description":"Currentdecimaldebt>balance.0Decimal,(greater than 0. REQUIRED)\ndebt_apr_pct:,decimalno0-100default.","type":"number"},"debt_type":{"description":"Debtastype:percentage'credit_card',e.g.'auto',6.5'student',not'personal',0.065or('mortgage'. REQUIRED)\nextra_monthly, no default.","type":"string"},"extra_monthly":{"description":"Extradecimalmonthly>amount0.availableThefor debt payoff or investing, the amount inquestionquestion.(REQUIRED)\nminimum_payment:Decimal,decimalgreater>=than00.(optional;REQUIRED,auto-calculatednofordefault.","type":"number"},"full_schedule":{"default":null,"description":"Whetherloanstowhenreturn0)\nterm_months_remaining:theintfull>month-by-month0.schedule.RequiredOptional;fordefaultsnon-credit-cardtodebtfalsetypes\ninvestment_return_pct:(compactdecimalschedule)0-30whenasomitted.","type":["boolean","null"]},"investment_return_pct":{"default":null,"description":"Expectedpercentageinvestment return, an EFFECTIVE ANNUAL rate; the monthly compounding step is (1+pct/100)^(1/12)-1-1.(optional;Decimal from 0 to 30. Optional; defaults to the cited long-run S&P 500 nominal return, about 10%)\ninvestment_volatility_pct:,decimalwhen(optional;omitted.","type":["number","null"]},"investment_tax_advantaged":{"default":null,"description":"Whetheraddsthevolatilityinvestmentriskisnote)\ntax_bracket_pct:tax-advantaged,decimale.g.0-100401kasorpercentageIRA.(optional;Optional;enablesdefaultsafter-taxtocomparison)\ninvestment_tax_advantaged:falseboolwhen(optionalomitted.","type":["boolean","null"]},"investment_volatility_pct":{"defaultfalse; set":null,"description":"Investmenttruevolatility.forDecimal.401k/IRA)\ntime_horizon_years:Optional;intadds>a0volatility(optional;riskdefaultnotemax(payoffwhenyearssupplied.",10))\nfull_schedule"type":bool (optional["number","null"]},"minimum_payment":{"defaultfalse;":null,"description":"Minimumreturnsmonthlycompactpayment.scheduleDecimal,byatdefault)\nchart_title:leaststring0.(optional)Optional;overrideauto-calculated forthe chart title. Mustamortizingnotloanscontainwhenem-dashesomitted oren-dashes. Max 120 characters.\n\nENVELOPE0.","type":\n["number","null"]},"output":{"default":null,"description":"'summary' (default)|, 'inline',|or'capture'\n summary:'capture'. 'summary' returns headline comparison scalars+, milestones,+andcitations;citations with monthly_scheduleisstripped.stripped.\n inline:'inline' returns the full payload including the month-by-month monthly_schedule[].(for'capture'chartwritesrendering).\n capture:the full payloadwrittento~/.senaro/captures/;~/.senaro/captures/capture_refandURIreturnsreturned.\n Availablecapture_ref; available on the local stdio transportonly;only, since the hosted HTTP transport rejects'capture'\n with a structured'capture'errorandnamingnames 'summary' and 'inline' as the valid alternatives.","type":["string","null"]},"tax_bracket_pct":{"default":null,"description":"Tax bracket, e.g. 22 not 0.22. Decimal from 0 to 100. Optional; enables an after-tax comparison when supplied.","type":["number","null"]},"term_months_remaining":{"default":null,"description":"Months remaining on the debt. Integer, greater than 0. Required for non-credit-card debt types; optional for credit_card.","type":["integer","null"]},"time_horizon_years":{"default":null,"description":"Projection horizon. Integer, greater than 0. Optional; defaults to the greater of the payoff horizon or 10 years when omitted.","type":["integer","null"]}},"required":["toolArgumentsdebt_type","debt_balance","debt_apr_pct","extra_monthly"],"type":"object"}
{"properties":{"toolArgumentschart_title":{"descriptiondefault":null,"JSON object with these parameters:\n\nREQUIRED:\n current_balance: decimal > 0. Outstanding principal you would refinance.\n current_annual_rate_pctdescription":decimal [0,"Reserved20]forastheachartpercentage,pipeline;e.g.validated6.5but not0.065.\n remaining_term_months:yetintused.[1,Must480].notMonthscontainleftem-dashesonortheen-dashes.currentMaxloan.\n new_annual_rate_pct:120decimalcharacters.[0Optional.",20] as a percentage. The offered rate.\n new_term_months"type":int[1"string",480"null"]. The new loan term.\n\nOPTIONAL},"closing_costs":\n current_monthly_payment{"default":decimalnull,"description":"Explicit>closing0.costsYourinactualdollars,statementexcludingP&Ipoints;payment;totaloverridesupfrontthe\n formula-derivedcostpaymentiswhenclosing_costssuppliedplus(matchtheyourpointsstatement).\n closing_costs:cost.decimalDecimal>=from0.0Explicittoclosing1,000,000,000.costsOptional;inomittingdollars;itoverridesuses thecited\ncited default(of 0.67% of the loan,(LodeStar 2026).Excludes points -- total upfront cost is\n closing_costs + points cost.An IMMEDIATE break-even requires total upfront cost tobe\nbe zero (or non-positive) AND monthly_savings to be non-negative, i.e. closing_costsAND\nAND points both 0, not closing_costs alone; a zero-total-cost refi into a worsedeal\ndeal (negative monthly_savings) reports NEAR_ZERO_OR_NEGATIVE_SAVINGSinstead.\n pointsinstead.","type":decimal[0"number",4"null"]},"compute_economic_break_even":{"default":null,"description":"Whether to compute the economic (defaultnet-worth0crossover).Discountbreak-even.pointsWhenatfalse,closingonly(1.0the=cash-flow1%break-evenofandloan).\n roll_costs_into_loan:interestbooldelta(defaultarefalse).returned,Whenand economic_break_even reports NOT_REQUESTED. Optional; defaults to true when omitted.","type":["boolean","null"]},"current_annual_rate_pct":{"description":"Currentclosingloan'scostsannual+ratepointsasareaaddedpercentage,to\n thee.g.new6.5 not 0.065. Decimal from 0 to 20. REQUIRED, no default.","type":"number"},"current_balance":{"description":"Outstanding principalinsteadyouofwouldpaidrefinance.upfront;Decimal,cash-flowgreaterbreak-eventhanthen0reportsandCOSTS_ROLLED_INTO_LOAN.\n investment_return_pctat most 1,000,000,000. REQUIRED, no default.","type":"number"},"current_monthly_payment":{"default":null,"description":"Yourdecimalactual[statement P&I payment. Decimal, greater than 0 and at most 1,000,000,000.30Optional; when supplied it overrides the formula-derived payment, so match your statement.","type":["number","null"]},"investment_return_pct":{"default":null,"description":"Annual return used for the economic (invest-the-savings) break-even, an EFFECTIVE ANNUAL rate; the monthly compoundingstep\nstep is (1+pct/100)^(1/12)-1-1.(default:Decimal~10.0%,from 0 to 30. Optional; omitting it uses the cited long-run S&P 500 nominal total-returndefault;default,call\nabout 10%; call list_defaults for the exact currentvalue).value.","type":["number","null"]},"new_annual_rate_pct":{"description":"TheAnnualofferedreturnrefinanceusedrateforastheaeconomic\n (invest-the-savings)percentage.break-even.\n compute_economic_break_evenDecimal from 0 to 20. REQUIRED, no default.","type":"number"},"new_term_months":{"description":"Theboolnew(loan term in months. Integer from 1 to 480. REQUIRED, no default.","type":"integer"},"points":{"default":null,"description":"Discounttrue).pointsWhenpaidfalseat closing,onlywhere 1.0 means 1% of thecash-flowloan.break-even\n andDecimalinterestfromdelta0aretoreturned4.(economicOptional;break-evendefaultsreportstoNOT_REQUESTED).\n chart_title0 when omitted.","type":["number","null"]},"remaining_term_months":{"description":"Monthsstringleft(optional).onReservedtheforcurrent loan. Integer from 1 to 480. REQUIRED, no default.","type":"integer"},"roll_costs_into_loan":{"default":null,"description":"Whether closing costs and points are added to thechartnewpipeline.principalMustinsteadnotofcontainpaidem-dashesupfront;orcash-flowen-dashes.break-evenMaxthen120reportscharacters.COSTS_ROLLED_INTO_LOAN. Optional; defaults to false when omitted.","type":["boolean","null"]}},"required":["toolArgumentscurrent_balance","current_annual_rate_pct","remaining_term_months","new_annual_rate_pct","new_term_months"],"type":"object"}
before
{"properties":{"toolArguments":{"description":"JSON object with parameters:\n\nTIER 0 - REQUIRED (the instant answer renders from these three):\n home_price: decimal > 0\n monthly_rent: decimal >= 0 (0 is valid for free-housing baseline)\n mortgage_rate_pct: decimal in (0, 100]; e.g. 6.75 for 6.75%. Never cached; provide current rate.\n\nTIER 1 - PRE-FILLED (defaults are cited; omit to use the default):\n down_payment_pct: decimal [0, 100] (default: 20%). 0 is valid (zero-down programs).\n loan_term_months: int > 0 (default: 360 = 30-year fixed)\n horizon_years: int [1, 40] (default: returns snapshots at years 5, 10, 30)\n hoa_monthly: decimal >= 0 (default: 0)\n\nTIER 2 - SOFT OVERRIDES (defaults from cited national sources; override for your market):\n home_appreciation_pct: decimal. Annual home price appreciation % (default: 4.25%, FHFA HPI).\n rent_growth_pct: decimal. Annual rent escalation % (default: 3.4%, BLS CPI ROPR).\n maintenance_pct: decimal. Annual maintenance as % of home value (default: 1.5%, Harvard JCHS).\n sell_side_pct: decimal. Sell-side transaction cost % of sale price (default: 7.5%, Redfin post-NAR).\n property_tax_pct: decimal. Annual property tax as % of home value (default: 0.88%).\n home_insurance_pct: decimal. Annual insurance as % of home value (default: 0.65%).\n pmi_pct: decimal. Annual PMI rate as % of loan (default: 0.5%). Removal threshold is set by pmi_removal_ltv_pct (below).\n pmi_removal_ltv_pct: decimal 50-100 (optional). Sets the loan-balance trigger for PMI removal: omitted, it is the 78% HPA automatic-termination threshold; provided (e.g. 80), it is whichever of 78% or your value is reached first. Either way PMI also stops at the statutory amortization midpoint of the original term (12 U.S.C. §4901(7), §4902(c)), which this value cannot postpone.\n investment_return_pct: decimal. RENT path annual return %, an EFFECTIVE ANNUAL rate; the monthly compounding step is (1+pct/100)^(1/12)-1 (default: 10.0%).\n inflation_pct: decimal. Inflation % for real-terms toggle (default: 2.5%).\n real_terms: bool. Deflate the output series for real-terms view (default: false).\n basis_capitalizable_pct_override: decimal [0, 100]. Fraction of the buy-side closing cost that is\n capitalizable into the §121 adjusted basis (IRS Pub 523 split: abstract fees, title search, recording fees,\n survey fees, transfer taxes, owner's title insurance). Default: 50% (Senaro deterministic midpoint).\n Supply your actual HUD-1 split when available. 0 = HomePrice-only basis; 100 = full closing cost in basis.\n\nTIER 3 - TAX REFINEMENT (only used when apply_tax_benefit = true):\n apply_tax_benefit: bool (default: false). The §121 home-sale gain exclusion applies only at sale\n points 24 months or more after purchase (IRC §121(a) 2-of-5-year test); year 1 of yearly_series,\n months 1-23 in monthly_series, and any horizon under 24 months use no exclusion. Separately,\n IRC §1222(3) makes a holding period of 12 months or less short-term, taxed at ordinary rates\n instead of the long-term rates otherwise applied, on the home-sale gain and the renter's\n portfolio gain alike (24 months vs. 12 months are two different thresholds); this tool applies that split exactly to the\n home-sale gain, and to the renter's portfolio at annual grain: prior years' contributions are\n compounded together as one long-term lot rather than aged individually, so months inside a year\n understate short-term gain.\n filing_status: 'Single' | 'MFJ' | 'MFS' | 'HoH' (REQUIRED when apply_tax_benefit = true)\n tax_year: 2025 | 2026 (REQUIRED when apply_tax_benefit = true)\n annual_gross_income: decimal >= 0 (REQUIRED when apply_tax_benefit = true; MAGI proxy for bracket/SALT)\n state_local_tax: decimal >= 0 (optional, default 0; SALT for the SALT cap, state income or sales tax paid)\n charitable: decimal >= 0 (optional, default 0; charitable contributions. TY2026+: 0.5%-AGI floor per OBBBA §70111)\n other_itemizable: decimal >= 0 (optional, default 0; medical above 7.5% AGI, casualty losses, etc.)\n age_65_plus_count: int 0 to 2 (optional; adds additional standard deduction per qualifying filer)\n blind_count: int 0 to 2 (optional; adds additional standard deduction per qualifying blind filer)\n loan_origination_date: string YYYY-MM-DD (optional; pre-12/15/2017 gets $1M cap, post gets $750k)\n pmi_annual: decimal >= 0 (optional; if omitted, derived from pmi_pct x average loan balance)\n purchase_year_points: decimal >= 0 (optional; discount points at origination, % of loan; paid in cash at closing and deducted in year 1)\n\nENVELOPE:\n output: 'summary' (default) | 'inline' | 'capture'\n summary: headline scalars + per-horizon snapshots; heavy series stripped (chart-friendly)\n inline: full payload including yearly_series[] + monthly_series[] (for chart rendering)\n capture: full payload written to ~/.senaro/captures/; capture_ref URI returned.\n Available on the local stdio transport only; the hosted HTTP transport rejects 'capture'\n with a structured error naming 'summary' and 'inline' as the valid alternatives.\n\nchart_title: string (optional) override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters."}},"required":["toolArguments"],"type":"object"}after
{"properties":{"age_65_plus_count":{"default":null,"description":"Number of filers aged 65 or older, each adding the additional standard deduction. Integer from 0 to 2. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["integer","null"]},"annual_gross_income":{"default":null,"description":"Annual gross income, the MAGI proxy for the bracket and the SALT cap. Decimal from 0 to 1,000,000,000. Required when apply_tax_benefit is true; otherwise not used.","type":["number","null"]},"apply_tax_benefit":{"default":null,"description":"Whether to apply the federal tax benefit model (TY2025/TY2026 SALT caps, mortgage interest deduction, PMI deductibility). When true, filing_status, tax_year and annual_gross_income are required. Optional; defaults to false when omitted. The §121 home-sale gain exclusion applies only at sale points 24 months or more after purchase (IRC §121(a) 2-of-5-year test); year 1 of yearly_series, months 1-23 in monthly_series, and any horizon under 24 months use no exclusion. Separately, IRC §1222(3) makes a holding period of 12 months or less short-term, taxed at ordinary rates instead of the long-term rates otherwise applied, on the home-sale gain and the renter's portfolio gain alike (24 months vs. 12 months are two different thresholds); this tool applies that split exactly to the home-sale gain, and to the renter's portfolio at annual grain: prior years' contributions are compounded together as one long-term lot rather than aged individually, so months inside a year understate short-term gain.","type":["boolean","null"]},"basis_capitalizable_pct_override":{"default":null,"description":"Percentage of the buy-side closing cost that is capitalizable into the §121 adjusted basis (IRS Pub 523 split: abstract fees, title search, recording fees, survey fees, transfer taxes, owner's title insurance). Decimal from 0 to 100; 0 means a HomePrice-only basis, 100 means the full closing cost is in basis. Optional; defaults to 50% (Senaro deterministic midpoint) when omitted. Supply your actual HUD-1 split when available.","type":["number","null"]},"blind_count":{"default":null,"description":"Number of blind filers, each adding the additional standard deduction. Integer from 0 to 2. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["integer","null"]},"charitable":{"default":null,"description":"Charitable contributions. Decimal from 0 to 1,000,000,000; TY2026 and later apply a 0.5%-of-AGI floor per OBBBA §70425. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"chart_title":{"default":null,"description":"Override for the chart title. Must not contain em-dashes or en-dashes. Max 120 characters. Optional.","type":["string","null"]},"down_payment_pct":{"default":null,"description":"Down payment as a percentage of the home price. Decimal from 0 to 100; 0 is valid (zero-down programs). Optional; defaults to 20% when omitted.","type":["number","null"]},"filing_status":{"default":null,"description":"Tax filing status: 'Single', 'MFJ', 'MFS' or 'HoH'. Required when apply_tax_benefit is true; otherwise not used.","type":["string","null"]},"hoa_monthly":{"default":null,"description":"Monthly HOA dues on the BUY path. Decimal from 0 to 1,000,000,000. Optional; defaults to 0 when omitted.","type":["number","null"]},"home_appreciation_pct":{"default":null,"description":"Annual home price appreciation as a percentage. Decimal from -50 to 50. Optional; defaults to the cited 4.25% (FHFA HPI) when omitted; override for your market.","type":["number","null"]},"home_insurance_pct":{"default":null,"description":"Annual home insurance as a percentage of home value. Decimal from 0 to 15. Optional; defaults to 0.65% when omitted; override for your market.","type":["number","null"]},"home_price":{"description":"Home purchase price. Decimal, greater than 0 and at most 1,000,000,000. REQUIRED, no default.","type":"number"},"horizon_years":{"default":null,"description":"Projection horizon in years. Integer from 1 to 40. Optional; when omitted, the response returns snapshots at years 5, 10 and 30.","type":["integer","null"]},"inflation_pct":{"default":null,"description":"Inflation as a percentage, for the real_terms toggle. Decimal, at least 0 and less than 100. Optional; when omitted, a nominal run uses 2.5%, and a real_terms run uses the horizon-based default: 2.0% for a horizon of 7 years or less, 2.6% for 8 to 19 years, 2.5% for 20 years or more.","type":["number","null"]},"investment_return_pct":{"default":null,"description":"RENT path annual return as a percentage, an EFFECTIVE ANNUAL rate; the monthly compounding step is (1+pct/100)^(1/12)-1. Decimal from -50 to 30. Optional; defaults to 10.0% when omitted.","type":["number","null"]},"loan_origination_date":{"default":null,"description":"Mortgage origination date, YYYY-MM-DD. Selects the mortgage interest deduction cap: on or before 2017-12-15 the $1M cap, after it the $750k cap (Single and MFJ; MFS caps are half). Only used when apply_tax_benefit is true. Optional; omitting it uses the post-2017 cap.","type":["string","null"]},"loan_term_months":{"default":null,"description":"Mortgage term in months. Integer from 1 to 480. Optional; defaults to 360 (a 30-year fixed) when omitted.","type":["integer","null"]},"maintenance_pct":{"default":null,"description":"Annual maintenance as a percentage of home value. Decimal from 0 to 20. Optional; defaults to the cited 1.5% (Harvard JCHS) when omitted; override for your market.","type":["number","null"]},"monthly_rent":{"description":"Monthly rent on the RENT path. Decimal from 0 to 1,000,000,000; 0 is valid (a free-housing baseline). REQUIRED, no default.","type":"number"},"mortgage_rate_pct":{"description":"Mortgage annual rate as a percentage, e.g. 6.75 for 6.75%. Decimal, greater than 0 and at most 100. Never cached; provide the current rate. REQUIRED, no default.","type":"number"},"other_itemizable":{"default":null,"description":"Other itemizable deductions, such as medical expenses above 7.5% of AGI or casualty losses. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"output":{"default":null,"description":"'summary' (default), 'inline', or 'capture'. 'summary' returns headline scalars and per-horizon snapshots with the heavy series stripped. 'inline' returns the full payload including yearly_series[] and monthly_series[] for chart rendering. 'capture' writes the full payload to ~/.senaro/captures/ and returns capture_ref; available on the local stdio transport only, since the hosted HTTP transport rejects 'capture' and names 'summary' and 'inline' as the valid alternatives.","type":["string","null"]},"pmi_annual":{"default":null,"description":"Annual PMI premium in dollars while PMI is active. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; when omitted it is derived from pmi_pct and the original loan amount.","type":["number","null"]},"pmi_pct":{"default":null,"description":"Annual PMI rate as a percentage of the loan. Decimal from 0 to 5. Optional; defaults to 0.5% when omitted. The removal threshold is set by pmi_removal_ltv_pct.","type":["number","null"]},"pmi_removal_ltv_pct":{"default":null,"description":"Loan-balance trigger for PMI removal, as a percentage loan-to-value. Decimal from 50 to 100. Optional; omitted, it is the 78% HPA automatic-termination threshold; provided (e.g. 80), it is whichever of 78% or your value is reached first. Either way PMI also stops at the statutory amortization midpoint of the original term (12 U.S.C. §4901(7), §4902(c)), which this value cannot postpone.","type":["number","null"]},"property_tax_pct":{"default":null,"description":"Annual property tax as a percentage of home value. Decimal from 0 to 10. Optional; defaults to 0.88% when omitted; override for your market.","type":["number","null"]},"purchase_year_points":{"default":null,"description":"Discount points paid at origination, as a percentage of the loan. Decimal from 0 to 4. Counted as cash paid at closing on every call; when apply_tax_benefit is true they are also deducted in year 1. Optional; defaults to 0 when omitted.","type":["number","null"]},"real_terms":{"default":null,"description":"Whether to deflate the output series to a real-terms view. Optional; defaults to false when omitted.","type":["boolean","null"]},"rent_growth_pct":{"default":null,"description":"Annual rent escalation as a percentage. Decimal from -50 to 50. Optional; defaults to the cited 3.4% (BLS CPI ROPR) when omitted; override for your market.","type":["number","null"]},"sell_side_pct":{"default":null,"description":"Sell-side transaction cost as a percentage of the sale price. Decimal from 0 to 25. Optional; defaults to the cited 7.5% (Redfin post-NAR) when omitted; override for your market.","type":["number","null"]},"state_local_tax":{"default":null,"description":"State and local tax paid (state income or sales tax), for the SALT cap. Decimal from 0 to 1,000,000,000. Only used when apply_tax_benefit is true. Optional; defaults to 0 when omitted.","type":["number","null"]},"tax_year":{"default":null,"description":"Tax year: 2025 or 2026. Integer. Required when apply_tax_benefit is true; otherwise not used.","type":["integer","null"]}},"required":["home_price","monthly_rent","mortgage_rate_pct"],"type":"object"}after
{"properties":{"bt_apr_pct":{"default":null,"description":"Balance-transfer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required when include_balance_transfer is true and bt_offers is omitted. bt_offers, when supplied, overrides this and the other three bt_* scalars below. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_fee_pct":{"default":null,"description":"Balance-transfer fee as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted. bt_offers, when supplied, overrides this. The 0-10 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_manual_transfers":{"default":null,"description":"Exact per-card transfer amounts. Required when bt_transfer_strategy is 'manual'; each entry's card_name must match a name in cards[]. Optional otherwise; a JSON null is treated as omitted, the same as leaving the field out.","items":{"properties":{"amount":{"description":"Dollar amount to transfer from this card, greater than $0, up to $1,000,000,000. Required per entry.","type":["number","null"]},"card_name":{"description":"Card name; must match a name in cards[]. Required per entry. Max 120 characters.","maxLength":120,"type":["string","null"]}},"type":["object","null"]},"type":["array","null"]},"bt_offers":{"default":null,"description":"Balance-transfer offers to compare head-to-head, 1 to 10, preferred over the four scalar bt_* fields above when comparing two or more offers: when supplied, bt_offers overrides bt_apr_pct, bt_promo_months, bt_regular_apr_pct, and bt_fee_pct, and their range checks are skipped. The response includes a balance_transfer_offers block with per-offer simulation results, selected_offer_index, selected_offer_label, selected_offer_reason, and all_offers_trap. Optional; a JSON null is rejected, unlike bt_manual_transfers and windfalls below, where a JSON null is treated as omitted.","items":{"properties":{"apr_pct":{"description":"Offer APR as a percentage, 0-100, e.g. 0 for a 0% promo. Required per offer.","maximum":100,"minimum":0,"type":["number","null"]},"fee_pct":{"description":"Balance-transfer fee for this offer, as a percentage of the transferred balance, 0-10. Optional; defaults to 3.0 when omitted.","type":["number","null"]},"label":{"description":"Label for this offer. Optional; defaults to '<apr_pct>% / <promo_months>mo' when omitted. Max 120 characters.","maxLength":120,"type":["string","null"]},"promo_months":{"description":"This offer's promo period in months, 1-60. Optional; defaults to 18 when omitted.","type":["integer","null"]},"regular_apr_pct":{"description":"APR that applies after this offer's promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted.","type":["number","null"]}},"type":["object","null"]},"maxItems":10,"type":["array","null"]},"bt_promo_months":{"default":null,"description":"Balance-transfer promo period in months, 1-60. Optional; defaults to 18 when omitted. bt_offers, when supplied, overrides this. The 1-60 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["integer","null"]},"bt_regular_apr_pct":{"default":null,"description":"APR that applies after the promo period ends, as a percentage, 0-100. Optional; defaults to 25.20 when omitted. bt_offers, when supplied, overrides this. The 0-100 range applies only when include_balance_transfer is true and bt_offers is omitted; a non-number is rejected in every case.","type":["number","null"]},"bt_transfer_limit":{"default":null,"description":"Cap on the total dollar amount transferred to the balance-transfer card, at least $0.01. When set, only this amount moves to the BT card; remaining balances stay on original cards, and a combined simulation runs both halves together, correctly redistributing freed minimum payments. Optional; when omitted, the entire balance is transferred (legacy behavior). Needs include_balance_transfer or bt_offers.","minimum":0.01,"type":["number","null"]},"bt_transfer_strategy":{"default":null,"description":"How to choose which balances move when bt_transfer_limit is less than your total debt: 'highest_apr_first' (transfer from highest-APR segments first, maximizes interest savings), 'highest_balance_first' (transfer largest balances first), or 'manual' (use bt_manual_transfers to specify exact amounts per card). Optional; defaults to 'highest_apr_first' when omitted. Needs bt_transfer_limit.","type":["string","null"]},"cards":{"description":"Credit cards to include, 1 to 20. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"cards must be a JSON array.\"); the two are not the same rejection. segments and stop_spend_month are not supported by this tool and are rejected; a non-zero monthly_spend, annual_fee, or plan_fees_monthly is rejected too, but zero (including an explicit 0) is accepted and dropped for all three: this tool always reads the flat purchase_balance / cash_advance_balance fields on each card below, never segments[] balances, and card-level fees and ongoing spend are not modeled here. Those five fields are supported by calculate_cc_payoff and compare_payoff_strategies instead.","items":{"properties":{"cash_advance_apr_pct":{"description":"Cash advance APR as a percentage, greater than 0, up to 100. Required when cash_advance_balance is greater than 0.","type":["number","null"]},"cash_advance_balance":{"description":"Cash advance balance in dollars, $0 to $1,000,000,000. Optional; defaults to 0 when omitted.","type":["number","null"]},"minimum_payment":{"description":"Minimum payment in dollars, $0 to $1,000,000,000. Optional; 0 or omitted auto-calculates the bank minimum. Used as the locked floor for the constant keep-cards payment: each card pays max(your minimum, the bank minimum), held constant and rolled forward as cards clear.","type":["number","null"]},"name":{"description":"Card label, e.g. 'Chase Sapphire'. Optional; a card without a name is auto-numbered ('Card 1', 'Card 2', ...). Max 120 characters.","maxLength":120,"type":["string","null"]},"purchase_apr_pct":{"description":"Purchase APR as a percentage, 0-100, e.g. 22.99. Required per card.","type":["number","null"]},"purchase_balance":{"description":"Purchase balance in dollars, $0 to $1,000,000,000. Required per card.","type":["number","null"]}},"type":"object"},"type":"array"},"chart_title":{"default":null,"description":"Override for the chart title. Optional; must not contain an em dash or en dash. Max 120 characters.","maxLength":120,"type":["string","null"]},"consolidation_loan":{"description":"Loan terms for the consolidation option. Required: omitting the field answers contract_error MISSING_REQUIRED_FIELD, while an explicit JSON null answers parse_error (\"consolidation_loan must be an object.\"); the two are not the same rejection.","properties":{"annual_rate_pct":{"description":"Annual interest rate for the consolidation loan, as a percentage, 0-36, e.g. 10.99. Required.","type":["number","null"]},"include_fee_in_principal":{"description":"Whether the origination fee is rolled into the loan principal rather than paid upfront. Optional; defaults to true when omitted. A JSON null is rejected; omit the field instead of sending null.","type":["boolean","null"]},"origination_fee_flat":{"description":"Flat-dollar origination fee, $0 to $10,000. Optional; defaults to 0 when omitted, and takes precedence over origination_fee_pct when it produces a larger fee. A JSON null is rejected; omit the field instead of sending null.","type":["number","null"]},"origination_fee_pct":{"description":"Origination fee as a percentage of loan principal, 0-10. Optional; defaults to 0 when omitted. A JSON null is rejected, unlike every other optional field on this tool; omit the field instead of sending null.","type":["number","null"]},"term_months":{"description":"Consolidation loan term in months, 12-84. Required.","type":["integer","null"]}},"type":"object"},"current_strategy":{"default":null,"description":"Your current payoff strategy, compared against the consolidation loan / balance-transfer alternative: 'avalanche' or 'snowball'. Optional; defaults to 'avalanche' when omitted. Case-sensitive.","enum":["avalanche","snowball",null],"type":["string","null"]},"extra_monthly_payment":{"default":null,"description":"Extra monthly payment in dollars, $0 to $1,000,000,000, applied on top of the required minimums for keep-cards and any balance transfer, and on top of the loan's own required payment for consolidation. Optional; defaults to 0 when omitted. fixed_payments is not a parameter of this tool, unlike calculate_cc_payoff: the keep-cards baseline is always simulated under the canonical constant rolled-forward payment (see comparison_basis in the response); supplying fixed_payments returns an unknown_parameter error.","type":["number","null"]},"full_schedule":{"default":null,"description":"Whether to return the full month-by-month amortization schedule instead of the compact default. Optional; defaults to false when omitted.","type":["boolean","null"]},"include_balance_transfer":{"default":null,"description":"Whether to run a single-offer balance-transfer scenario using the four scalar bt_* fields below. Optional; defaults to false when omitted. Ignored once bt_offers is supplied; use bt_offers when comparing two or more offers.","type":["boolean","null"]},"output":{"description":"Valid values: 'summary' (default), 'inline'. summary: compact response with a data_preview block; no heavy array exists on this response today, so summary and inline are currently identical in content. inline: full payload (currently identical to summary; will diverge once a heavy array is added for chart rendering).","enum":["summary","inline",null],"type":["string","null"]},"windfalls":{"default":null,"description":"One-time principal payments, at most 12, same shape as calculate_cc_payoff. Optional; a JSON null is treated as omitted, the same as leaving the field out. When non-empty, the response adds windfalls_applied[] and windfalls_unused[] on keep_cards, on each balance_transfer scenario (and on each offer in balance_transfer_offers.offers[]), on consolidation_loan (single-row per windfall since the loan is a single-balance instrument), and on optimized_consolidation.keep_subset. All scenarios use with-windfalls totals so cross-option ranking stays apples-to-apples, except what_if.same_budget_accelerated, a windfall-free hypothetical about extra-payment behavior, not your actual lump-sum schedule.","items":{"properties":{"amount":{"description":"Dollar amount of the windfall, greater than 0. Required per entry.","type":["number","null"]},"label":{"description":"Optional label for this windfall, e.g. 'Tax refund' or 'Year-end bonus'. Max 120 characters.","maxLength":120,"type":["string","null"]},"month":{"description":"Month index the windfall is applied, 0 or more. 0 means applied before month 1's interest; N >= 1 applies at the end of calendar month N. Required per entry.","type":["integer","null"]}},"type":["object","null"]},"type":["array","null"]}},"required":["cards","consolidation_loan"],"type":"object"}