Tax optimizer
Cut taxes across accounts and years by orchestrating the public planfi MCP. Use whenever someone wants to lower their tax bill, time ISO exercises or Roth conversions, build a Roth conversion ladder, find mega-backdoor / after-tax 401(k) space, check NIIT / AMT / state surtax exposure, optimize charitable giving — bunch donations into a donor-advised fund (DAF) to clear the standard deduction, take a QCD at 70½+ that lowers AGI/IRMAA/Social-Security taxation, or give long-term appreciated stock/RSUs in-kind to avoid capital gains while still deducting FMV — realize long-term gains at the 0% capital-gains rate in a low-income year (tax-gain harvesting) — how much gain can I harvest at 0% before NIIT/IRMAA? — harvest lot-level unrealized losses to offset realized gains and up to $3,000 of ordinary income, flag wash sales, suggest replacement securities (tax-loss harvesting) — weigh retirement relocation / state-tax arbitrage — "should I retire in / move to a lower-tax state? compare the lifetime after-tax outcome of state A vs B" — check whether you qualify for the federal Saver's Credit (up to 50% of retirement contributions for lower/moderate income) — or size a 72(t)/SEPP substantially-equal-payment stream for penalty-free access to retirement money before 59½ — e.g. "how do I cut my taxes with $900k in a 401k?", "convert my IRA to Roth between 60 and 70 filling the 12% bracket — how much each year?", "how much after-tax 401(k) space do I have?", "what's the full NIIT/AMT bite on an ISO exercise?", "I'm retiring in CA but thinking about TX — how much do I keep over my lifetime?".From its SKILL.md
npx -y skills add KameronKales/planfi-skills --skill tax-optimizerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
37.6 KB, ~9.7k tokens by cl100k_base, as published. Nobody here has run it
Tax Optimizer
A thin orchestration layer over the planfi MCP (https://ai.planfi.app/mcp/free).
All tax math, brackets, and limits live server-side. This skill only gathers inputs and calls the
tools — it does not compute anything locally and bakes in no defaults of its own. Read-only.
Every tool returns a structured assumed_defaults[] array ({ field, assumed_value, note })
listing each input it had to assume — always read these back to the user.
Related skills: for high-W2 execs weighing an employer Nonqualified Deferred Comp (NQDC / 409A)
election — defer-now-vs-take-now, lump-vs-installment distribution, and smoothing the distribution
years' brackets / IRMAA — see deferred-comp (analyze_deferred_comp).
Step 0 — Make sure the planfi tools are connected
This skill uses these tools (may be namespaced, e.g. mcp__planfi__analyze_tax_optimization):
analyze_tax_optimization, optimize_multi_year_tax, analyze_roth_conversion,
analyze_mega_backdoor_roth, analyze_advanced_taxes, analyze_gain_harvesting,
analyze_tax_loss_harvesting, analyze_tax_lots, analyze_charitable_giving, analyze_opportunity_zone,
analyze_relocation, analyze_savers_credit, analyze_72t_sepp, analyze_hsa_retirement, plus optional generate_financial_plan
(for plan_id chaining + a share_url). Use whichever name your environment exposes (bare or
mcp__planfi__-prefixed); below they are written bare.
If they're NOT available, tell the user to connect the MCP, then continue:
claude mcp add --transport http planfi https://ai.planfi.app/mcp/free
Try free, then add your key. The command above adds the free connector —
https://ai.planfi.app/mcp/free(no key needed). Once you create an API key, add a new connector with the MCP url —https://ai.planfi.app/mcp— and authorize it with your key.
(On claude.ai: add a custom connector pointing at https://ai.planfi.app/mcp/free.)
Access — free for personal use. The planfi MCP is free to try (a small monthly allowance, no key needed). Heavy automated abuse forced us to add limits — but it stays free for personal use: email [email protected] and we'll send you a free API key, no charge. (Companies and commercial use have paid plans.) To use a key, pass it as an
Authorization: Bearer pft_…header in your MCP client config.
Step 1 — (Optional) build a plan first to chain context + get a share link
Feed it into the forecast (not just plan_id chaining):
generate_financial_plannow acceptsgain_harvestingdirectly as a plan input, so it flows into net worth, FIRE %, and Monte-Carlo backtesting — the 0%-LTCG harvest is applied as a one-time tax effect. Use the standalone analyze tool below for a focused what-if; passgain_harvestinginto the plan to see its effect on the whole household forecast.
If the user has (or wants) a full household model, call generate_financial_plan once and
capture the returned plan_id. The plan-aware tools in this skill accept { plan_id } (plus inline overrides),
so they can resolve balances, income, age, and filing status from the saved plan instead of you
re-sending every figure. Every tax tool also returns a share_url (planfi.app) when you pass
a plan_id that resolves a saved household — without a plan_id there is no plan to share, so no
share_url is emitted. generate_financial_plan is the way to mint a plan_id (and its own
share_url) when the session has no model yet.
This step is optional: every tax tool runs cold from raw inputs too. Prefer the plan path when the session already has a model or the user wants a sharable artifact.
Engine facts to bake in: all decimals are fractions (24% →
0.24); all dollars are today's (real) dollars; brackets/limits are approximate ~2026 values. Overridetax_yearon any tool if the user needs a different year.
Step 2 — Route by intent
Pick the tool that matches what the user is asking. Pass { plan_id } when you have one; otherwise
pass the raw fields below. Every field is optional with a sensible server default unless marked
REQUIRED — so the tools run even from sparse input (every assumption is reported back in the
structured assumed_defaults[] array, see Step 3).
"Lower my taxes broadly" → analyze_tax_optimization
Asset location + tax-loss harvesting + charitable bunching/QCD, with quantified annual $ savings.
Useful fields: taxable_balance, tax_deferred_balance, roth_balance, ordinary_tax_rate,
capital_gains_tax_rate, age; toggles enable_asset_location (default on), enable_tlh,
enable_charitable. For TLH add realized_capital_gains, harvestable_losses,
loss_carryforward. For charitable add annual_charitable_giving, bunch_years, qcd_amount.
analyze_tax_optimization({
taxable_balance: 400000, tax_deferred_balance: 900000,
ordinary_tax_rate: 0.24, age: 52,
enable_tlh: true, realized_capital_gains: 30000, harvestable_losses: 12000
})
"Time my ISO exercise + Roth conversions over several years" → optimize_multi_year_tax
AMT-crossover / NIIT-threshold / IRMAA-tier aware year-by-year plan.
REQUIRED: baseline_ordinary_income. Optional: iso_shares_to_exercise (total bargain element to
exercise-and-hold), total_roth_to_convert, horizon_years, target_magi_ceiling,
filing_status.
"Roth conversion ladder in my gap years" → analyze_roth_conversion
Fills conversions to the top of a target bracket and models lifetime RMD tax avoided.
REQUIRED: traditional_balance, current_age. Optional: conversion_start_age,
conversion_end_age, target_bracket_rate, birth_year (sets RMD start age 73 vs 75),
filing_status, other_taxable_income, state_flat_rate, life_expectancy. ISO/NIIT layering via
enable_amt + iso_bargain_element, enable_niit + net_investment_income. Conversions raise
MAGI — flag the ACA-subsidy interaction and point pre-65 retirees to the retirement-income skill's
analyze_healthcare_bridge (this is your own suggestion, not a server next_actions edge — those
chain to analyze_withdrawal_strategy, analyze_gain_harvesting, and analyze_relocation).
analyze_roth_conversion({
traditional_balance: 800000, current_age: 60,
conversion_start_age: 60, conversion_end_age: 70,
target_bracket_rate: 0.12, filing_status: "married_joint", birth_year: 1966
})
"After-tax 401(k) / backdoor Roth space" → analyze_mega_backdoor_roth
415(c) total-addition limit, remaining after-tax space, and Roth-IRA phaseout / pro-rata detection.
REQUIRED: age, annual_salary, employee_401k_contribution. Optional: employer_match or
employer_match_formula, magi, filing_status, existing_pretax_ira_balance (triggers pro-rata
warning), existing_nondeductible_ira_basis.
"Full surtax bite — NIIT / AMT / state" → analyze_advanced_taxes
The three surtax layers on top of ordinary tax.
REQUIRED: ordinary_taxable_income. Optional: net_investment_income, magi (NIIT threshold),
iso_bargain_element (AMT), state_flat_rate, filing_status. Good as a sanity check after a Roth
conversion or ISO exercise.
"How much gain can I realize at 0%?" → analyze_gain_harvesting
Tax-gain harvesting (the mirror of tax-loss harvesting): how much long-term capital gain you can
realize at the 0% LTCG rate (or up to the 15% band) in a low-income year before the next
bracket, NIIT, or an IRMAA cliff bites. Returns the harvestable amount at 0%, the
per-tranche tax cost (0% / 15% / 20% bands), the basis step-up benefit of resetting basis at
0%, and the binding cliff to avoid (LTCG breakpoint / NIIT / IRMAA).
Useful fields: unrealized_ltcg_gain (or position_value + cost_basis to derive the embedded
gain), ordinary_taxable_income, existing_realized_ltcg (gains already booked this year that eat
0%-bracket room), filing_status, magi (drives NIIT + IRMAA), age (IRMAA only applies at the
≥63 look-back age), future_ltcg_rate (rate the step-up avoids), and target_max_ltcg_rate
(0 to stay in the 0% band, 0.15 to also fill the 15% band). Complements the TLH path in
analyze_tax_optimization — losses offset gains, gain-harvesting books gains for free.
analyze_gain_harvesting({
unrealized_ltcg_gain: 80000, ordinary_taxable_income: 50000,
filing_status: "married_joint", magi: 115000, age: 55, target_max_ltcg_rate: 0
})
"Should I bunch my donations? / front-load a donor-advised fund / give appreciated stock instead of cash / use a QCD from my IRA to cover my RMD / how do I give to charity tax-efficiently / clear the standard deduction by bunching / donate my RSUs / avoid capital gains by donating / lower my AGI with a QCD?" → analyze_charitable_giving
Always CALL analyze_charitable_giving for these — do not answer from general knowledge or quote the standard-deduction / 60%-AGI / QCD-cap rules of thumb from memory. When the user gives the numbers, run it and lead with its real output (recommended strategy, estimated tax savings, bunching schedule, AGI-limit headroom). This is the first-class charitable analyzer for high earners (32–37% brackets) with charitable intent and/or concentrated appreciated positions. It compares four levers and recommends the highest-savings one:
- BUNCHING / DAF — concentrate several years of giving into one year (or front-load a donor-advised-fund lump sum) so the bunch-year itemized deductions clear the 2026 standard deduction; itemize in the bunch year, take the standard deduction in off-years. The
bunchingblock returnsbunchedDonation,deductionGain, the per-yearschedule[]({ year, donation, deductionTaken, itemizes }), andtaxSavings(zero benefit when per-year itemized already beats the standard deduction — the tool tells you). - APPRECIATED SECURITIES vs cash — donating long-term appreciated stock at fair-market value avoids the capital-gains tax AND NIIT on the embedded gain while still taking the full FMV deduction. The
appreciatedblock returnsunrealizedGain,capGainsAvoided,niitAvoided,fmvDeduction, andtaxSavingsVsCash(the in-kind edge over selling-then-donating, where the FMV deduction is identical). - QCD (age 70½+) — a Qualified Charitable Distribution satisfies the RMD while excluding the amount from AGI (capped at the 2026 QCD cap). The
qcdblock returnseligible,rmd,qcdApplied,cap, andtaxSavings. - AGI deduction limits — the
agi_limitsblock returnscashLimit(60% AGI),appreciatedLimit(30% AGI),cashHeadroom,appreciatedHeadroom, and any 5-yearcarryforwardof excess.
Top-level returns: recommended_strategy, estimated_tax_savings, the four blocks above, and an assumptions[] list. Useful fields (every one optional, plan-resolved when omitted): age, filing_status, adjusted_gross_income (alias agi) — drives the 60%/30% AGI limits + NIIT, ordinary_taxable_income (the bracket base + QCD marginal-rate lookup — never a flat assumed rate), ira_balance (alias rmd_amount), birth_year, annual_donation (alias cash_donation), years_to_bunch, other_itemized_deductions, appreciated_securities_value, appreciated_cost_basis, daf_contribution, qcd_amount, state_code, tax_year, plan_id.
analyze_charitable_giving({
filing_status: "married_joint", age: 72,
ordinary_taxable_income: 380000, adjusted_gross_income: 400000,
annual_donation: 15000, other_itemized_deductions: 8000, years_to_bunch: 3,
appreciated_securities_value: 50000, appreciated_cost_basis: 10000,
ira_balance: 500000, qcd_amount: 20000
})
// → recommended_strategy + estimated_tax_savings, with bunching{bunchedDonation,deductionGain,taxSavings,schedule[]},
// appreciated{unrealizedGain,capGainsAvoided,niitAvoided,fmvDeduction,taxSavingsVsCash},
// qcd{eligible,rmd,qcdApplied,cap,taxSavings}, agi_limits{cashLimit,appreciatedLimit,cashHeadroom,appreciatedHeadroom,carryforward}
Chain note: complements analyze_gain_harvesting (donate the most-appreciated lots instead of harvesting/selling them — the appreciated-securities overlap), analyze_rmd (a QCD satisfies the RMD it sizes — the QCD overlap), and analyze_irmaa (the QCD's AGI exclusion is what relieves an IRMAA tier).
"Harvest my losses / offset my gains / what can I write off / will this trigger a wash sale / what do I buy instead / sell my losers for the tax break?" → analyze_tax_loss_harvesting
Always CALL analyze_tax_loss_harvesting for these — do not answer from general knowledge or quote
the $3,000 / 30-day rules of thumb from memory. When the user gives lots and a gain budget, run it
and lead with its real output (harvestable amount, tax saved, wash-sale flags, replacement
suggestions). Tax-loss harvesting is the mirror of gain-harvesting: it identifies lot-level
unrealized losses, nets them against realized ST/LT gains (IRC §1211/§1212 order), applies up to
$3,000 against ordinary income, carries the rest forward, flags wash-sale windows (30-day,
cross-account incl. spouse/IRA, IRC §1091), and suggests correlated-but-not-substantially-identical
replacement securities. Returns harvestable_loss, disallowed_loss, wash_sale_lots[],
net_short_term / net_long_term, ordinary_offset, tax_benefit, niit_savings,
loss_carryforward_to_next_year, replacement_suggestions[], and a netting_steps[] audit trail.
Useful fields: lots[] (each { costBasis, marketValue, term: 'short'|'long', symbol?, account?, recentPurchaseDates?[] }), realizedShortTermGain, realizedLongTermGain,
shortTermLossCarryforward, longTermLossCarryforward, ordinaryTaxableIncome, filingStatus,
magi (NIIT), harvestDate, age. Federal-only in v1 (most states disallow/cap the $3k
net-loss-against-ordinary deduction). The replacement map never names the same CUSIP/index — the
substantially-identical judgment is the user's.
analyze_tax_loss_harvesting({
lots: [
{ symbol: "VTI", costBasis: 60000, marketValue: 48000, term: "long" },
{ symbol: "VXUS", costBasis: 30000, marketValue: 22000, term: "short",
recentPurchaseDates: ["2026-12-01"] }
],
realizedLongTermGain: 40000, ordinaryTaxableIncome: 120000, filingStatus: "married_joint"
})
"Which lots should I sell? / HIFO vs FIFO vs specific-ID / which shares to sell to minimize tax / can I harvest a crypto loss and rebuy immediately / will selling these specific lots trigger a wash sale / pick the lots that maximize my harvested loss / short-term vs long-term on these lots?" → analyze_tax_lots
Always CALL analyze_tax_lots for these — do not answer from general knowledge or quote the HIFO / FIFO / §1091 30-day / "crypto isn't a security" rules of thumb from memory. When the user gives the lots (qty, basis, acquire date) + a sale quantity and price, run it and lead with its real output (the recommended lot-selection set per method, realized ST vs LT gain/loss, wash-sale-disallowed loss + basis adjustment, the crypto-vs-equity treatment difference, and after-tax proceeds + tax saved). This is the lot-level optimizer — distinct from analyze_tax_loss_harvesting / analyze_gain_harvesting, which work on the portfolio AGGREGATE. Use this one whenever the question is about which individual purchase lots to sell. It compares HIFO (highest-basis first → max loss / min gain), FIFO, and specific-ID; splits short-term vs long-term per lot by acquire date; applies the §1091 wash-sale disallowance to equity lots sold at a loss (the disallowed loss adds to the replacement lot's basis); and models the crypto carve-out (crypto is property, not a security — wash-sale does NOT apply under current law, so the loss is harvestable and you can repurchase immediately), with apply_crypto_wash_sale to model proposed future law. Returns recommended_lots[], realized_short_term_gain / realized_long_term_gain, wash_sale_disallowed_loss, basis_adjustment, crypto_vs_equity_difference, after_tax_proceeds, tax_saved, and a method_comparison[] (HIFO/FIFO/specific side-by-side). Federal-only; ST gain at the ordinary marginal rate, LT gain via the LTCG bracket stack, plus NIIT.
analyze_tax_lots({
asset_class: "equity",
filing_status: "single", ordinary_taxable_income: 50000,
lots: [
{ id: "L1", qty: 100, cost_basis_per_share: 50, acquire_date: "2024-01-01" },
{ id: "L2", qty: 100, cost_basis_per_share: 90, acquire_date: "2025-12-01" }
],
sale_qty: 100, current_price_per_share: 70, method: "HIFO"
})
Chain note: roll the harvested losses into analyze_tax_loss_harvesting (the aggregate view + wash-sale-safe replacements), realize the chosen long-term-gain lots at 0% via analyze_gain_harvesting in a low-income year, or run the realized gain through analyze_advanced_taxes for the full NIIT/bracket picture.
"Big realized capital gain — Opportunity Zone / QOF / defer or eliminate cap-gains tax" → analyze_opportunity_zone
Real-user phrasings: "I have a $X capital gain, should I roll it into an Opportunity Zone?", "How much tax can a QOF defer?", "Opportunity Zone fund vs just paying the cap-gains tax now", "10-year QOF step-up", "defer capital gains real estate / stock sale", "can a Qualified Opportunity Fund eliminate my gain?"
Always CALL analyze_opportunity_zone for these — do not answer from general knowledge or quote the 180-day / 10-year / step-up rules of thumb from memory. When the user gives the realized gain (+ growth rate, hold years), run it and lead with its real output: deferred gain + deferred tax + recognition date, the 10-year eliminated tax on appreciation, the side-by-side ending after-tax value, and the NPV advantage of the QOF vs paying now.
Models a Qualified Opportunity Fund (QOF / Opportunity Zone) for a large realized capital gain (real estate or equity). (1) GAIN DEFERRAL — rolling an eligible realized gain into a QOF within the 180-day window DEFERS the tax until the statutory recognition/inclusion date (current law); returns the deferred gain, the deferred tax (cap-gains + NIIT + optional state), and the recognition year. (2) 10-YEAR ELIMINATION / STEP-UP-TO-FMV — holding the QOF 10+ years steps basis up to FMV at sale, ELIMINATING all tax on the QOF's own appreciation; quantifies the eliminated tax for a given growth rate over the hold. (3) NPV DEFER-VS-PAY-NOW — compares paying cap-gains+NIIT now and investing the after-tax remainder in a taxable equivalent (net of annual dividend/turnover drag the QOF avoids) vs deferring via the QOF and taking the 10-year elimination, present-valuing both at a discount rate; returns the side-by-side ending after-tax value and the NPV advantage of the QOF.
Useful fields (every one optional, plan-resolved when omitted): eligibleGain (the realized gain rolled in), ordinaryTaxableIncome (LTCG stacking base), filingStatus, magi (NIIT), qofGrowthRate, holdYears (≥10 → elimination), discountRate, taxableDragRate (dividend×turnover-tax drag the QOF avoids), stateFlatRate, recognitionYear (override), gainRealizationDateISO (anchors the 180-day window), tax_year, plan_id.
analyze_opportunity_zone({
filingStatus: "married_joint", eligibleGain: 1000000,
ordinaryTaxableIncome: 400000, qofGrowthRate: 0.07, holdYears: 10
})
// → deferred_gain + deferred_tax + recognition_date, eliminated_tax_on_appreciation (10y step-up),
// pay_now_ending_after_tax vs qof_ending_after_tax, npv_advantage_of_qof (headline)
Chain note: roll the realized gain through analyze_advanced_taxes for the full NIIT/bracket picture, or use analyze_stock_concentration / analyze_gain_harvesting as upstream entry points (a concentrated-position sale or harvested gain is exactly the eligible gain that feeds a QOF).
"Should I retire in / move to a lower-tax state?" → analyze_relocation
Lifetime after-tax comparison of state A vs B: state income tax, capital-gains, retirement-income &
Social-Security taxation, property tax, state estate tax, plus a cost-of-living delta. Returns the
annual + lifetime difference, a one-time estate-tax delta, and a move / stay / marginal
recommendation with the dominant driver named.
REQUIRED: from_state, to_state (two-letter codes). Optional: annual_retirement_income,
social_security_income, annual_capital_gains, annual_spend (at COL index 100),
real_estate_value, filing_status, current_age, life_expectancy (sets the horizon),
liquid_assets, mortgage_principal, estimated_growth_rate, tax_year, and plan_id /
overrides (plan resolution). State income tax comes from the server's shared engine
(state-tax.ts): progressive bracket tables for all 50 states + DC, with first-class single and
married-filing-jointly (MFJ) brackets, so filing_status branches every state (no-income-tax states
report $0). There is no state_flat_rate field on this tool — brackets are server-side, not
user-supplied. Federal income & estate tax are state-invariant and excluded from the delta; figures
are real-dollar, undiscounted.
Shared bracket engine —
n/a (shared engine: state-tax.ts). The progressive 50-state + DC single/MFJ bracket tables (with per-state surtaxes) live in one shared engine module (state-tax.ts) reused by every tool here and by therelocation-plannerskill — there is no CA/NY/MA-only special-casing and no per-tool flat-rate fallback. For a relocation-only question (no broader tax work), therelocation-plannerskill wraps the sameanalyze_relocationtool as a focused entry point.
Like every tool in this skill, analyze_relocation emits a structured assumed_defaults[]
array (every state-profile fallback it applied — no-SS-tax, $0 retirement-income exclusion, default
property rate, the 85% Social-Security convention) and a share_url when you pass { plan_id }.
Read back the assumed_defaults[] and offer the link. Because this is a near-retiree decision, pair
it with the retirement-income skill (analyze_withdrawal_strategy, optimize_social_security
— now a full SSA benefit pipeline: NAWI indexing, projected bend points, COLA, and trust-fund-cut
scenarios from an earnings_history — and analyze_estate_exposure) for the full decumulation
picture once the state is chosen.
"Do I qualify for the Saver's Credit?" → analyze_savers_credit
The federal Saver's Credit (Retirement Savings Contributions Credit, IRC §25B): a non-refundable
credit of 50% / 20% / 10% of up to $2,000 per person of IRA + elective-deferral contributions,
phased out by AGI and filing status. The server owns every AGI breakpoint and tier — do not hardcode
thresholds here.
Useful fields: agi, filing_status, retirement_contributions (IRA + 401(k)/403(b) elective deferrals),
age, is_student, is_dependent (the three eligibility gates — under-18, full-time student, or claimed
as a dependent all disqualify). Returns the credit rate/band, eligible contributions counted, the gross and
allowed (liability-capped) credit, and whether it was capped by your tax liability.
analyze_savers_credit({
agi: 34000, filing_status: "single",
retirement_contributions: 2000, age: 27
})
// → 50% band → ~$1,000 credit on $2,000 of Roth IRA contributions (non-refundable, capped to tax owed)
"Access retirement money penalty-free before 59½" → analyze_72t_sepp
72(t) substantially-equal-periodic-payments (SEPP): how much you can pull from an IRA/401(k) each year
penalty-free before 59½ by committing to a fixed-formula stream for the longer of 5 years or until age
59½. The server owns the divisor table and the max(5%, 120% mid-term AFR) interest-rate cap — no thresholds
live here.
Useful fields: account_balance, current_age, method (amortization / rmd / annuitization),
interest_rate. Returns the annual distribution for the chosen method, all three methods side-by-side, the
commitment-window years, whether the rate is within the §72(t) max, and the retroactive-10%-penalty warning if
the SEPP is modified early.
analyze_72t_sepp({
account_balance: 1000000, current_age: 52,
method: "amortization", interest_rate: 0.05
})
// → fixed annual SEPP withdrawal, locked in for the longer of 5 yrs or age 59½
"Should I max my HSA and invest it? / Is the HSA a good retirement account? / triple-tax-advantaged / save medical receipts and reimburse later / receipt shoebox / deferred reimbursement / how much can I contribute to my HSA in 2026 / family vs self HSA limit / age-55 HSA catch-up / can I keep contributing past 65 / HSA after Medicare / use HSA for non-medical after 65" → analyze_hsa_retirement
Always CALL analyze_hsa_retirement for these — do not answer from general knowledge or quote the contribution-limit / triple-tax / age-65 rules of thumb from memory. When the user gives the numbers, run it and lead with its real output (recommended contribution + invest decision, projected tax-free medical reserve, receipt-banking advantage in $, age-65 withdrawal recommendation, lifetime tax saved vs spending annually).
The HSA-as-retirement optimizer treats the HSA as the only triple-tax-advantaged investable retirement vehicle and models four levers deterministically (compounding + bracket math, no Monte Carlo):
- MAX-FUND + INVEST vs spend — 2026 family/individual contribution limits + the age-55 $1,000 catch-up (server-sourced from
tax-limits, never hardcoded), deposit-then-grow compounding to retirement. - RECEIPT-SHOEBOX / DEFERRED REIMBURSEMENT — pay current qualified medical out-of-pocket, bank the unreimbursed receipts, reimburse tax-free decades later after the balance compounds; quantifies the invest-and-defer advantage in dollars (
receipt_banking_advantage_dollars) and the breakeven horizon. - 6-MONTHS-BEFORE-MEDICARE contribution stop and its interaction with working past 65 under an employer HDHP (
medicare_contribution_stop_age). - AGE-65 PIVOT — after 65 non-medical withdrawals are penalty-free but taxable (traditional-IRA-equivalent) while qualified-medical withdrawals stay tax-free (
age_65_withdrawal_recommendation).
Useful fields (every one optional, plan-resolved when omitted): current_age, retirement_age, coverage_type (individual/family), current_hsa_balance, annual_contribution, invest_balance (boolean), expected_real_return, annual_qualified_medical_oop (the receipt-banking candidate, paid from cash), marginal_tax_rate (else derived from income), filing_status, working_past_65, medicare_enrollment_age, tax_year, plan_id, overrides. Returns recommended_annual_contribution, invest_recommendation, projected_tax_free_medical_reserve_at_retirement, receipt_banking_advantage_dollars, age_65_withdrawal_recommendation, lifetime_tax_saved_vs_spending_annually, contribution_limit_2026, catch_up_eligible, medicare_contribution_stop_age, and breakeven_year.
analyze_hsa_retirement({
current_age: 35, retirement_age: 65, coverage_type: "family",
invest_balance: true, expected_real_return: 0.07,
annual_qualified_medical_oop: 2000, filing_status: "married_joint",
marginal_tax_rate: 0.24
})
// → recommended max contribution + "invest", projected tax-free medical reserve at 65,
// receipt-banking advantage in $, age-65 withdrawal recommendation, lifetime tax saved vs spending annually
Pairs with
retirement-incomeandfinancial-forecast: a 72(t) is an early-retirement decumulation bridge — pair it with theretirement-incomeskill'sanalyze_withdrawal_strategy/analyze_healthcare_bridgefor the pre-Medicare income+coverage picture, and use thefinancial-forecastskill to see the SEPP floor inside a full household projection. The Saver's Credit matters most for early-career accumulators — fold it into a forecast viafinancial-forecastto see it land on the federal tax line.
Step 3 — Surface results honestly
For whichever tool you called:
- Lead with the headline dollar figure — annual tax savings, per-year conversion amounts + lifetime RMD tax avoided, AMT/NIIT crossover, remaining after-tax space, total surtax bite.
- Read back the assumptions verbatim. Every tax tool returns a structured
assumed_defaults[]array — each entry is{ field, assumed_value, note }for an input it had to assume (e.g. ordinary rate 0.24, cap-gains 0.15, bond allocation 0.2, standard deduction $29,200; Roth target bracket 0.12, RMD age 73, life expectancy 92). Read each one back so the user can correct any silent default. (disclosures.key_assumptionsis separate static explanatory prose — not the assumption list; the machine-readable record lives inassumed_defaults[].) - Honor
disclosures.not_advice(a boolean flag, not a message) — present results as planning estimates, not tax advice. - Follow
next_actions[]— each is{ tool, why, prefilled_args }(carrying{ plan_id }when available). Use these server-suggested chains rather than guessing the next call. - For a share link: every tax tool returns a
share_urlwhen called with a{ plan_id }that resolves a saved household; without aplan_idno link is emitted, so rungenerate_financial_plan(Step 1) first to mint aplan_idand surface itsshare_url.
Recommended call sequence (typical session)
- (optional)
generate_financial_plan→ captureplan_id(+share_url). - Route by intent → one of the tools above (with
{ plan_id }or raw fields). - Read back the headline + the structured
assumed_defaults[]. - Follow
next_actions[](for these tools the edges chain intoanalyze_advanced_taxes,analyze_gain_harvesting,analyze_withdrawal_strategy,analyze_estate_exposure,analyze_relocation,analyze_hsa_retirement, oranalyze_self_employed_retirement).
Fictional examples
1. "I'm 52, $900k in a 401k and $400k taxable, 24% bracket — how do I cut my taxes?"
→ analyze_tax_optimization({ tax_deferred_balance: 900000, taxable_balance: 400000, ordinary_tax_rate: 0.24, age: 52 }). Lead with the annual asset-location tax-drag savings; offer to
turn on enable_tlh / enable_charitable if they have realized gains or giving intent. Read back
the assumed_defaults[] (cap-gains rate, allocation, standard deduction).
2. "I want to convert my traditional IRA to Roth between 60 and 70, MFJ, filling the 12% bracket
— how much each year?" → analyze_roth_conversion({ traditional_balance: <ask>, current_age: 60, conversion_start_age: 60, conversion_end_age: 70, target_bracket_rate: 0.12, filing_status: "married_joint" }). Lead with per-year conversion + lifetime RMD tax avoided; flag the MAGI/ACA
interaction and suggest analyze_healthcare_bridge if pre-65.
3. "We're retiring in California but thinking about Texas — $80k of IRA withdrawals, $40k Social
Security, a $600k house, ~$60k spend. Worth the move?" → analyze_relocation({ from_state: "CA", to_state: "TX", annual_retirement_income: 80000, social_security_income: 40000, real_estate_value: 600000, annual_spend: 60000, filing_status: "married_joint" }). Lead with the total lifetime
advantage and the move/stay/marginal call; name the dominant driver (often state income tax or
COL). Read back the assumptions (esp. the 85% Social-Security convention and any no-table state).
4. "We retired early — basically $0 ordinary income this year, MFJ, and we're sitting on $300k of
unrealized long-term gains in a brokerage account. How much can we sell at 0% tax?" →
analyze_gain_harvesting({ unrealized_ltcg_gain: 300000, ordinary_taxable_income: 0, filing_status: "married_joint", target_max_ltcg_rate: 0 }). Lead with the harvestable-at-0% figure
(room up to the 0%/15% LTCG breakpoint), the $0 tax cost of that tranche, and the basis step-up
benefit of resetting cost basis at no cost. Name the binding cliff — here the 15% LTCG
breakpoint (and, if magi/age push them near it, the NIIT or IRMAA threshold). Note this is the
mirror of tax-loss harvesting and pairs with a Roth conversion (both spend the same 0%-bracket room,
so sequence them).
5. "We're 72, MFJ, ~$380k taxable / $400k AGI, give ~$15k/yr to charity, hold $50k of stock (basis $10k), and have $500k in a traditional IRA. Should I bunch into a DAF, give the appreciated shares, and do a QCD from our IRA?" →
analyze_charitable_giving({ filing_status: "married_joint", age: 72, ordinary_taxable_income: 380000, adjusted_gross_income: 400000, annual_donation: 15000, other_itemized_deductions: 8000, years_to_bunch: 3, appreciated_securities_value: 50000, appreciated_cost_basis: 10000, ira_balance: 500000, qcd_amount: 20000 }). Lead with recommended_strategy and estimated_tax_savings; break out the levers — bunching.deductionGain × marginal rate (with the per-year bunching.schedule[]), the in-kind appreciated.capGainsAvoided + appreciated.niitAvoided (the gain-avoidance edge over selling-then-donating, where appreciated.fmvDeduction is identical), the qcd.qcdApplied AGI exclusion, and the agi_limits headroom (cashHeadroom / appreciatedHeadroom / any carryforward). Read back the assumptions[] (30%/60%-AGI ceilings, 5-yr carryforward, QCD cap and age 70½). Pairs with analyze_gain_harvesting (donate the most-appreciated lots), analyze_rmd (the QCD satisfies the RMD), and analyze_irmaa.
(All examples use fictional figures — never reuse a real user's numbers in documentation.)
Notes
- All decimals are fractions; all dollars are today's (real) dollars; brackets/limits are ~2026
(override
tax_yearas needed). - Pass
{ plan_id }to reuse a saved household model; any field you also pass is a shallow override. - Every tax tool surfaces its assumptions as a structured
assumed_defaults[]array ({ field, assumed_value, note }) — read each entry back.disclosures.key_assumptionsis separate static prose anddisclosures.not_adviceis a boolean. Each tool also returns ashare_urlwhen passed aplan_idthat resolves a household; with noplan_id, rungenerate_financial_planfor a sharable link. - Tax-loss harvesting (
analyze_tax_loss_harvesting) is the mirror of tax-gain harvesting (analyze_gain_harvesting): TLH nets lot-level losses against realized gains, deducts up to $3,000 against ordinary income, flags wash sales, and suggests replacements; gain-harvesting books gains at the 0% rate. Callanalyze_tax_loss_harvestingwhenever the user has losing lots and a gain budget. - Tax-gain harvesting (
analyze_gain_harvesting) complements tax-loss harvesting (analyze_tax_loss_harvesting): losses offset realized gains, while gain-harvesting books long-term gains at the 0% rate and steps up basis for free. It also pairs withanalyze_roth_conversion— both consume the same 0%-bracket / low-income headroom, so a household with limited room must choose how to spend it (sequence the two rather than double-count the space). - Charitable giving (
analyze_charitable_giving) is the dedicated optimizer for donors and holders of concentrated appreciated positions. Its three levers cross-link the rest of the suite: in-kind appreciated-stock donation is the better move whenanalyze_gain_harvestingshows a large embedded gain (donate the lot instead of selling it — you avoid the capital-gains tax AND NIIT and still deduct FMV); a QCD at 70½+ satisfies the RMD thatanalyze_rmdsizes while excluding it from AGI; and that AGI exclusion is exactly what relieves an IRMAA tier inanalyze_irmaa. Callanalyze_charitable_givingwhenever the user mentions giving, a DAF, a QCD, or donating appreciated stock/RSUs — don't quote the 60%-of-AGI / QCD-age / standard-deduction rules of thumb from memory. - Near-retiree weighing a move? Pair this with the
retirement-incomeskill for the decumulation side (withdrawal order, Social Security claiming age, estate-tax exposure). - Self-employed / S-corp owner? The
self-employed-plannerskill sizes Solo 401(k) / SEP / SIMPLE room, the §199A QBI deduction, and the S-corp reasonable-salary tradeoff. - Not financial or tax advice. Planning estimates only.
What ships with it: 3 files
6.1 KB alongside SKILL.md
.claude-plugin/
- plugin.json700 B
Gives 0 of the 12 instructions most finance skills give in ~9.7k tokens
Counted across 469 of the 469 authors here whose files we hold, read 2026-08-07
- Extract date vendor amount and descriptionin 15 of 469, across 3 files
- Scan folder for invoice filesin 14 of 469, across 2 files
- Rename files to standard formatin 14 of 469, across 2 files
- Show organization plan before movingin 14 of 469, across 2 files
- Generate summary CSVin 14 of 469, across 2 files
- Organize files by categoryin 13 of 469, across 1 file
- Preserve original filesin 13 of 469, across 1 file
- Flag files missing critical infoin 13 of 469, across 1 file
- Produce the requested output filein 9 of 469, across 4 files
- Build best, base, and worst case scenariosin 9 of 469, across 5 files
- Implement backoff if rate limit errors occurin 8 of 469, across 3 files
- Determine the weighted average cost of capitalin 8 of 469, across 4 files
Said here and by no other author read
- use planfi MCP tools
- do not compute tax math locally
- read assumed defaults back to the user
- tell the user to connect the MCP if tools are missing
- capture the returned plan id when generating a plan
- pass plan id when available
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.