analyze_education_tax_benefits
Compare education tax benefits including AOTC, Lifetime Learning Credit, student loan interest deduction, and 529 plan advantages to optimize tax savings.
Instructions
Compare education tax benefits: AOTC vs Lifetime Learning Credit, student loan interest deduction, and 529 plan advantages.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| filingStatus | Yes | ||
| agi | Yes | Adjusted Gross Income | |
| tuitionPaid | Yes | Tuition and qualified expenses paid | |
| isUndergrad | Yes | Is the student in first 4 years of undergrad? | |
| yearsAOTCClaimed | No | Years AOTC already claimed (max 4) | |
| studentLoanInterest | No | Student loan interest paid this year | |
| has529Plan | No | Contributing to or using a 529 plan | |
| contribution529 | No | 529 plan contribution this year |
Implementation Reference
- src/tools/planning-tools.ts:430-545 (handler)Main handler function for analyze_education_tax_benefits that compares AOTC vs Lifetime Learning Credit, calculates student loan interest deduction, and provides 529 plan information. Includes phase-out calculations based on AGI and filing status.
async (params) => { const lines = [ `## Education Tax Benefits Analysis`, `**AGI**: $${fmt(params.agi)} | **Filing**: ${params.filingStatus.replace(/_/g, " ")}`, "", ]; // AOTC analysis const aotcYearsUsed = params.yearsAOTCClaimed ?? 0; const aotcAvailable = params.isUndergrad && aotcYearsUsed < 4; const aotcPhaseout: Record<FilingStatus, [number, number]> = { single: [80000, 90000], married_filing_jointly: [160000, 180000], married_filing_separately: [0, 0], // not eligible head_of_household: [80000, 90000], }; const [aotcStart, aotcEnd] = aotcPhaseout[params.filingStatus]; let aotcCredit = 0; let aotcEligible = false; if (aotcAvailable && params.agi <= aotcEnd && params.filingStatus !== "married_filing_separately") { aotcEligible = true; const qualifiedExpenses = Math.min(params.tuitionPaid, 4000); aotcCredit = Math.min(2000, qualifiedExpenses) + Math.max(0, qualifiedExpenses - 2000) * 0.25; if (params.agi > aotcStart) { const reduction = (params.agi - aotcStart) / (aotcEnd - aotcStart); aotcCredit = Math.round(aotcCredit * (1 - reduction)); } } // LLC analysis const llcPhaseout: Record<FilingStatus, [number, number]> = { single: [80000, 90000], married_filing_jointly: [160000, 180000], married_filing_separately: [0, 0], head_of_household: [80000, 90000], }; const [llcStart, llcEnd] = llcPhaseout[params.filingStatus]; let llcCredit = 0; let llcEligible = false; if (params.agi <= llcEnd && params.filingStatus !== "married_filing_separately") { llcEligible = true; llcCredit = Math.min(params.tuitionPaid, 10000) * 0.20; if (params.agi > llcStart) { const reduction = (params.agi - llcStart) / (llcEnd - llcStart); llcCredit = Math.round(llcCredit * (1 - reduction)); } } lines.push( `### Credit Comparison`, `| Credit | Amount | Refundable | Eligible |`, `|--------|--------|------------|----------|`, `| AOTC | $${fmt(Math.round(aotcCredit))} | 40% ($${fmt(Math.round(aotcCredit * 0.4))}) | ${aotcEligible ? "✅" : "❌"} |`, `| Lifetime Learning | $${fmt(Math.round(llcCredit))} | No | ${llcEligible ? "✅" : "❌"} |`, "", ); const bestCredit = aotcEligible && aotcCredit >= llcCredit ? "AOTC" : llcEligible ? "Lifetime Learning Credit" : "Neither"; lines.push(`💡 **Best option**: ${bestCredit}`); if (aotcEligible && aotcCredit > llcCredit) { lines.push(`> AOTC is better: higher credit ($${fmt(Math.round(aotcCredit))} vs $${fmt(Math.round(llcCredit))}), plus 40% is refundable. ${4 - aotcYearsUsed} year(s) of AOTC remaining.`); } // Student loan interest const slInterest = params.studentLoanInterest ?? 0; if (slInterest > 0) { const slLimit = Math.min(slInterest, 2500); const slPhaseout: Record<FilingStatus, [number, number]> = { single: [80000, 95000], married_filing_jointly: [165000, 195000], married_filing_separately: [0, 0], head_of_household: [80000, 95000], }; const [slStart, slEnd] = slPhaseout[params.filingStatus]; let deduction = slLimit; if (params.agi > slEnd || params.filingStatus === "married_filing_separately") { deduction = 0; } else if (params.agi > slStart) { deduction = Math.round(slLimit * (1 - (params.agi - slStart) / (slEnd - slStart))); } lines.push( "", `### Student Loan Interest Deduction`, `| Item | Amount |`, `|------|--------|`, `| Interest Paid | $${fmt(slInterest)} |`, `| Deductible Amount | $${fmt(deduction)} |`, deduction < slLimit ? `| Lost to phase-out | $${fmt(slLimit - deduction)} |` : "", ); } // 529 plan if (params.has529Plan) { const contribution = params.contribution529 ?? 0; lines.push( "", `### 529 Plan`, `- Contributions are NOT federally deductible (check your state — many offer state tax deductions)`, `- Growth is tax-free for qualified education expenses`, `- Can be used for tuition, room & board, books, computers`, `- K-12 tuition: up to $10,000/year`, `- Unused funds: can roll to beneficiary's Roth IRA (up to $35K lifetime, 15+ year account)`, contribution > 0 ? `- Your contribution: $${fmt(contribution)} (gift tax exclusion: $${params.filingStatus === "married_filing_jointly" ? "38,000" : "19,000"}/year per beneficiary)` : "", ); } lines.push( "", `> ⚠️ Cannot claim both AOTC and LLC for the same student in the same year. MFS cannot claim education credits.`, ); return { content: [{ type: "text", text: lines.filter(Boolean).join("\n") }] }; } - src/tools/planning-tools.ts:420-429 (schema)Zod schema definition for analyze_education_tax_benefits tool input parameters including filingStatus, AGI, tuitionPaid, isUndergrad, yearsAOTCClaimed, studentLoanInterest, has529Plan, and contribution529.
{ filingStatus: FilingStatusEnum, agi: z.number().min(0).describe("Adjusted Gross Income"), tuitionPaid: z.number().min(0).describe("Tuition and qualified expenses paid"), isUndergrad: z.boolean().describe("Is the student in first 4 years of undergrad?"), yearsAOTCClaimed: z.number().int().min(0).max(4).optional().describe("Years AOTC already claimed (max 4)"), studentLoanInterest: z.number().min(0).optional().describe("Student loan interest paid this year"), has529Plan: z.boolean().optional().describe("Contributing to or using a 529 plan"), contribution529: z.number().min(0).optional().describe("529 plan contribution this year"), }, - src/tools/planning-tools.ts:415-546 (registration)Complete tool registration using server.tool() that defines the tool name, description, schema, and handler for analyze_education_tax_benefits within the registerPlanningTools function.
// --- Tool 5: Education tax benefits --- server.tool( "analyze_education_tax_benefits", "Compare education tax benefits: AOTC vs Lifetime Learning Credit, " + "student loan interest deduction, and 529 plan advantages.", { filingStatus: FilingStatusEnum, agi: z.number().min(0).describe("Adjusted Gross Income"), tuitionPaid: z.number().min(0).describe("Tuition and qualified expenses paid"), isUndergrad: z.boolean().describe("Is the student in first 4 years of undergrad?"), yearsAOTCClaimed: z.number().int().min(0).max(4).optional().describe("Years AOTC already claimed (max 4)"), studentLoanInterest: z.number().min(0).optional().describe("Student loan interest paid this year"), has529Plan: z.boolean().optional().describe("Contributing to or using a 529 plan"), contribution529: z.number().min(0).optional().describe("529 plan contribution this year"), }, async (params) => { const lines = [ `## Education Tax Benefits Analysis`, `**AGI**: $${fmt(params.agi)} | **Filing**: ${params.filingStatus.replace(/_/g, " ")}`, "", ]; // AOTC analysis const aotcYearsUsed = params.yearsAOTCClaimed ?? 0; const aotcAvailable = params.isUndergrad && aotcYearsUsed < 4; const aotcPhaseout: Record<FilingStatus, [number, number]> = { single: [80000, 90000], married_filing_jointly: [160000, 180000], married_filing_separately: [0, 0], // not eligible head_of_household: [80000, 90000], }; const [aotcStart, aotcEnd] = aotcPhaseout[params.filingStatus]; let aotcCredit = 0; let aotcEligible = false; if (aotcAvailable && params.agi <= aotcEnd && params.filingStatus !== "married_filing_separately") { aotcEligible = true; const qualifiedExpenses = Math.min(params.tuitionPaid, 4000); aotcCredit = Math.min(2000, qualifiedExpenses) + Math.max(0, qualifiedExpenses - 2000) * 0.25; if (params.agi > aotcStart) { const reduction = (params.agi - aotcStart) / (aotcEnd - aotcStart); aotcCredit = Math.round(aotcCredit * (1 - reduction)); } } // LLC analysis const llcPhaseout: Record<FilingStatus, [number, number]> = { single: [80000, 90000], married_filing_jointly: [160000, 180000], married_filing_separately: [0, 0], head_of_household: [80000, 90000], }; const [llcStart, llcEnd] = llcPhaseout[params.filingStatus]; let llcCredit = 0; let llcEligible = false; if (params.agi <= llcEnd && params.filingStatus !== "married_filing_separately") { llcEligible = true; llcCredit = Math.min(params.tuitionPaid, 10000) * 0.20; if (params.agi > llcStart) { const reduction = (params.agi - llcStart) / (llcEnd - llcStart); llcCredit = Math.round(llcCredit * (1 - reduction)); } } lines.push( `### Credit Comparison`, `| Credit | Amount | Refundable | Eligible |`, `|--------|--------|------------|----------|`, `| AOTC | $${fmt(Math.round(aotcCredit))} | 40% ($${fmt(Math.round(aotcCredit * 0.4))}) | ${aotcEligible ? "✅" : "❌"} |`, `| Lifetime Learning | $${fmt(Math.round(llcCredit))} | No | ${llcEligible ? "✅" : "❌"} |`, "", ); const bestCredit = aotcEligible && aotcCredit >= llcCredit ? "AOTC" : llcEligible ? "Lifetime Learning Credit" : "Neither"; lines.push(`💡 **Best option**: ${bestCredit}`); if (aotcEligible && aotcCredit > llcCredit) { lines.push(`> AOTC is better: higher credit ($${fmt(Math.round(aotcCredit))} vs $${fmt(Math.round(llcCredit))}), plus 40% is refundable. ${4 - aotcYearsUsed} year(s) of AOTC remaining.`); } // Student loan interest const slInterest = params.studentLoanInterest ?? 0; if (slInterest > 0) { const slLimit = Math.min(slInterest, 2500); const slPhaseout: Record<FilingStatus, [number, number]> = { single: [80000, 95000], married_filing_jointly: [165000, 195000], married_filing_separately: [0, 0], head_of_household: [80000, 95000], }; const [slStart, slEnd] = slPhaseout[params.filingStatus]; let deduction = slLimit; if (params.agi > slEnd || params.filingStatus === "married_filing_separately") { deduction = 0; } else if (params.agi > slStart) { deduction = Math.round(slLimit * (1 - (params.agi - slStart) / (slEnd - slStart))); } lines.push( "", `### Student Loan Interest Deduction`, `| Item | Amount |`, `|------|--------|`, `| Interest Paid | $${fmt(slInterest)} |`, `| Deductible Amount | $${fmt(deduction)} |`, deduction < slLimit ? `| Lost to phase-out | $${fmt(slLimit - deduction)} |` : "", ); } // 529 plan if (params.has529Plan) { const contribution = params.contribution529 ?? 0; lines.push( "", `### 529 Plan`, `- Contributions are NOT federally deductible (check your state — many offer state tax deductions)`, `- Growth is tax-free for qualified education expenses`, `- Can be used for tuition, room & board, books, computers`, `- K-12 tuition: up to $10,000/year`, `- Unused funds: can roll to beneficiary's Roth IRA (up to $35K lifetime, 15+ year account)`, contribution > 0 ? `- Your contribution: $${fmt(contribution)} (gift tax exclusion: $${params.filingStatus === "married_filing_jointly" ? "38,000" : "19,000"}/year per beneficiary)` : "", ); } lines.push( "", `> ⚠️ Cannot claim both AOTC and LLC for the same student in the same year. MFS cannot claim education credits.`, ); return { content: [{ type: "text", text: lines.filter(Boolean).join("\n") }] }; } ); - src/index.ts:47-47 (registration)Registration call to registerPlanningTools(server) which includes the analyze_education_tax_benefits tool among 6 planning tools.
registerPlanningTools(server); // 6 tools: planning tips, year compare, SE tax, mortgage, education, MFJ vs MFS