@markcolabs/mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +263 -0
- package/dist/disclaimers/ymyl.d.ts +16 -0
- package/dist/disclaimers/ymyl.d.ts.map +1 -0
- package/dist/disclaimers/ymyl.js +20 -0
- package/dist/disclaimers/ymyl.js.map +1 -0
- package/dist/engines/compoundInterest.d.ts +73 -0
- package/dist/engines/compoundInterest.d.ts.map +1 -0
- package/dist/engines/compoundInterest.js +72 -0
- package/dist/engines/compoundInterest.js.map +1 -0
- package/dist/engines/data/federalTax.d.ts +47 -0
- package/dist/engines/data/federalTax.d.ts.map +1 -0
- package/dist/engines/data/federalTax.js +111 -0
- package/dist/engines/data/federalTax.js.map +1 -0
- package/dist/engines/data/irs2026.d.ts +30 -0
- package/dist/engines/data/irs2026.d.ts.map +1 -0
- package/dist/engines/data/irs2026.js +30 -0
- package/dist/engines/data/irs2026.js.map +1 -0
- package/dist/engines/data/ssa.d.ts +39 -0
- package/dist/engines/data/ssa.d.ts.map +1 -0
- package/dist/engines/data/ssa.js +55 -0
- package/dist/engines/data/ssa.js.map +1 -0
- package/dist/engines/mortgage.d.ts +69 -0
- package/dist/engines/mortgage.d.ts.map +1 -0
- package/dist/engines/mortgage.js +59 -0
- package/dist/engines/mortgage.js.map +1 -0
- package/dist/engines/paycheck.d.ts +89 -0
- package/dist/engines/paycheck.d.ts.map +1 -0
- package/dist/engines/paycheck.js +109 -0
- package/dist/engines/paycheck.js.map +1 -0
- package/dist/engines/retirement401k.d.ts +105 -0
- package/dist/engines/retirement401k.d.ts.map +1 -0
- package/dist/engines/retirement401k.js +126 -0
- package/dist/engines/retirement401k.js.map +1 -0
- package/dist/engines/socialSecurity.d.ts +59 -0
- package/dist/engines/socialSecurity.d.ts.map +1 -0
- package/dist/engines/socialSecurity.js +135 -0
- package/dist/engines/socialSecurity.js.map +1 -0
- package/dist/envelope.d.ts +76 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +34 -0
- package/dist/envelope.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/bounds.d.ts +83 -0
- package/dist/shared/bounds.d.ts.map +1 -0
- package/dist/shared/bounds.js +121 -0
- package/dist/shared/bounds.js.map +1 -0
- package/dist/tools/compoundInterest.d.ts +48 -0
- package/dist/tools/compoundInterest.d.ts.map +1 -0
- package/dist/tools/compoundInterest.js +107 -0
- package/dist/tools/compoundInterest.js.map +1 -0
- package/dist/tools/mortgage.d.ts +51 -0
- package/dist/tools/mortgage.d.ts.map +1 -0
- package/dist/tools/mortgage.js +112 -0
- package/dist/tools/mortgage.js.map +1 -0
- package/dist/tools/paycheck.d.ts +54 -0
- package/dist/tools/paycheck.d.ts.map +1 -0
- package/dist/tools/paycheck.js +122 -0
- package/dist/tools/paycheck.js.map +1 -0
- package/dist/tools/retirement401k.d.ts +85 -0
- package/dist/tools/retirement401k.d.ts.map +1 -0
- package/dist/tools/retirement401k.js +141 -0
- package/dist/tools/retirement401k.js.map +1 -0
- package/dist/tools/socialSecurity.d.ts +51 -0
- package/dist/tools/socialSecurity.d.ts.map +1 -0
- package/dist/tools/socialSecurity.js +117 -0
- package/dist/tools/socialSecurity.js.map +1 -0
- package/dist/util/zod-to-json-schema.d.ts +28 -0
- package/dist/util/zod-to-json-schema.d.ts.map +1 -0
- package/dist/util/zod-to-json-schema.js +98 -0
- package/dist/util/zod-to-json-schema.js.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# @markcolabs/mcp
|
|
2
|
+
|
|
3
|
+
Model Context Protocol (MCP) server for **digitalcalculator.info** financial calculators.
|
|
4
|
+
|
|
5
|
+
**Status:** v0.1.0 — first public release. Sprint 136 hits the P12 O5-KR1 **5-tool target** and lifts the `private:true` flag for `npm publish`.
|
|
6
|
+
|
|
7
|
+
Locks in the contract from **ADR-0039** (MCP Tool Contract & Calc-Engine Lift).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What ships in v0.1.0
|
|
12
|
+
|
|
13
|
+
| Tool | Purpose |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `dc.calculator.mortgage.monthlyPayment` | Monthly principal & interest, total interest, total paid for a fixed-rate mortgage. |
|
|
16
|
+
| `dc.calculator.compoundInterest.futureValue` | Future value of a principal with optional monthly contributions, at a chosen compounding frequency. |
|
|
17
|
+
| `dc.calculator.401k.projection` | Year-by-year 401(k) projection through retirement, honoring IRS 2026 contribution limits (incl. SECURE 2.0 super catch-up for ages 60-63). |
|
|
18
|
+
| `dc.calculator.socialSecurity.estimate` | SSA bend-point PIA estimate with early-claim reduction, delayed-credit math, and lifetime projection. |
|
|
19
|
+
| `dc.calculator.paycheck.netPay` | IRS 2026 federal Percentage Method + FICA + simplified state-tax estimate (no state-specific tables, SDI, or local taxes — see methodology link). |
|
|
20
|
+
|
|
21
|
+
| Resource | Purpose |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `dc://disclaimers/ymyl` | Canonical YMYL disclaimer string returned in every tool response. |
|
|
24
|
+
|
|
25
|
+
Every tool response carries the `ToolResult<T>` envelope:
|
|
26
|
+
|
|
27
|
+
```jsonc
|
|
28
|
+
{
|
|
29
|
+
"result": { /* tool-specific structured payload */ },
|
|
30
|
+
"disclaimer": "Estimates only — for educational purposes...",
|
|
31
|
+
"methodology": {
|
|
32
|
+
"url": "https://www.digitalcalculator.info/mortgage-calculator/",
|
|
33
|
+
"version": "2026-05-09"
|
|
34
|
+
},
|
|
35
|
+
"calculatedAt": "2026-05-09T18:32:11.123Z",
|
|
36
|
+
"engineVersion": "0.1.0"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Failures funnel through the `ToolError` shape (never thrown to the transport):
|
|
41
|
+
|
|
42
|
+
```jsonc
|
|
43
|
+
{
|
|
44
|
+
"error": {
|
|
45
|
+
"code": "INPUT_VALIDATION",
|
|
46
|
+
"message": "Number must be greater than or equal to 0",
|
|
47
|
+
"field": "principal",
|
|
48
|
+
"retriable": false
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Code namespaces: `INPUT_VALIDATION`, `BUSINESS_RULE`, `INTERNAL`, `RATE_LIMIT` (only `RATE_LIMIT` is retriable).
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Local install + test
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cd packages/mcp
|
|
61
|
+
npm install
|
|
62
|
+
npm test # run parity + envelope tests
|
|
63
|
+
npm run build # compile TypeScript to dist/
|
|
64
|
+
npm start # boot MCP server over stdio
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Vitest runs `test/parity/*.test.ts` (per-tool parity vs site source) and `test/envelope.test.ts` (envelope contract). Parity tests must pass before any engine change is shipped.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Connecting from a local MCP client
|
|
72
|
+
|
|
73
|
+
After `npm run build`, point your MCP-compatible client at `node /path/to/packages/mcp/dist/index.js` over stdio. Example Claude Desktop config snippet:
|
|
74
|
+
|
|
75
|
+
```jsonc
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"digitalcalculator": {
|
|
79
|
+
"command": "node",
|
|
80
|
+
"args": ["/absolute/path/to/packages/mcp/dist/index.js"]
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The server emits a single startup line on stderr and then speaks JSON-RPC over stdio per the MCP spec.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Tool input/output sketches
|
|
91
|
+
|
|
92
|
+
### `dc.calculator.401k.projection`
|
|
93
|
+
|
|
94
|
+
```jsonc
|
|
95
|
+
// Input
|
|
96
|
+
{
|
|
97
|
+
"currentBalance": 25000,
|
|
98
|
+
"annualSalary": 80000,
|
|
99
|
+
"contributionPercent": 6, // % of salary
|
|
100
|
+
"employerMatchPercent": 50, // 50% match...
|
|
101
|
+
"employerMatchLimitPercent": 6, // ...up to 6% of salary
|
|
102
|
+
"annualSalaryGrowthPercent": 3, // 3%/yr; 0 mirrors site engine
|
|
103
|
+
"annualReturnPercent": 7,
|
|
104
|
+
"currentAge": 35,
|
|
105
|
+
"retirementAge": 65,
|
|
106
|
+
"catchUpEnabled": true // optional, default true
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Result payload
|
|
110
|
+
{
|
|
111
|
+
"futureBalance": 873421.55,
|
|
112
|
+
"totalContributions": 228450.12,
|
|
113
|
+
"employerContribTotal": 114225.06,
|
|
114
|
+
"growthEarned": 530746.37,
|
|
115
|
+
"yearByYear": [
|
|
116
|
+
{ "year": 1, "age": 36, "employeeContribution": 4944.00,
|
|
117
|
+
"employerMatch": 2472.00, "growth": 1750.00,
|
|
118
|
+
"endingBalance": 34166.00 }
|
|
119
|
+
/* ...30 rows */
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### `dc.calculator.socialSecurity.estimate`
|
|
125
|
+
|
|
126
|
+
```jsonc
|
|
127
|
+
// Input
|
|
128
|
+
{
|
|
129
|
+
"birthYear": 1965,
|
|
130
|
+
"currentEarnings": 80000,
|
|
131
|
+
"claimAge": 67, // 62..70
|
|
132
|
+
"yearsWorked": 35, // optional, default 35
|
|
133
|
+
"lifeExpectancy": 85 // optional, default 85
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Result payload
|
|
137
|
+
{
|
|
138
|
+
"monthlyBenefitAtFRA": 2104.50,
|
|
139
|
+
"adjustedMonthlyBenefit": 2104.50,
|
|
140
|
+
"lifetimeBenefitProjection": 454572,
|
|
141
|
+
"fraAge": 67.0,
|
|
142
|
+
"eligibilityYear": 2027,
|
|
143
|
+
"bendPointsEstimated": true
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
For an authoritative estimate based on actual 35-year earnings history,
|
|
148
|
+
direct callers to <https://www.ssa.gov/myaccount/>.
|
|
149
|
+
|
|
150
|
+
### `dc.calculator.paycheck.netPay`
|
|
151
|
+
|
|
152
|
+
```jsonc
|
|
153
|
+
// Input
|
|
154
|
+
{
|
|
155
|
+
"grossAnnualSalary": 80000,
|
|
156
|
+
"payFrequency": "biweekly", // weekly | biweekly | semimonthly | monthly | quarterly | annual
|
|
157
|
+
"federalFilingStatus": "single", // single | married | marriedSeparate | headOfHousehold
|
|
158
|
+
"state": "CA",
|
|
159
|
+
"dependents": 0,
|
|
160
|
+
"preTaxDeductionsAnnual": 4800,
|
|
161
|
+
"postTaxDeductionsAnnual": 0
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Result payload
|
|
165
|
+
{
|
|
166
|
+
"grossPerPaycheck": 3076.92,
|
|
167
|
+
"federalTax": 320.45,
|
|
168
|
+
"ficaTax": 215.61,
|
|
169
|
+
"stateTax": 116.91,
|
|
170
|
+
"netPay": 2240.43,
|
|
171
|
+
"payPeriodsPerYear": 26,
|
|
172
|
+
"federalTaxAnnual": 8331.70,
|
|
173
|
+
"ficaTaxAnnual": 5605.86,
|
|
174
|
+
"stateTaxAnnual": 3039.66,
|
|
175
|
+
"netPayAnnual": 58282.78,
|
|
176
|
+
"noStateIncomeTax": false
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
> v0.2.0 limitation: state withholding is `$0` for the 9 no-income-tax states
|
|
181
|
+
> (AK, FL, NV, NH, SD, TN, TX, WA, WY) and a flat 5% estimate over taxable
|
|
182
|
+
> income elsewhere. Per-state brackets, SDI, and local taxes are NOT modeled.
|
|
183
|
+
> See the methodology link for the full site calculator.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## Architecture
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
packages/mcp/
|
|
191
|
+
├── package.json # private:false (v0.1.0)
|
|
192
|
+
├── CHANGELOG.md
|
|
193
|
+
├── tsconfig.json
|
|
194
|
+
├── vitest.config.ts
|
|
195
|
+
├── src/
|
|
196
|
+
│ ├── index.ts # MCP server entry; tools/list, tools/call, resources/list
|
|
197
|
+
│ ├── envelope.ts # ToolResult<T>, ToolError types + helpers
|
|
198
|
+
│ ├── disclaimers/ymyl.ts # Canonical YMYL disclaimer (single source of truth)
|
|
199
|
+
│ ├── shared/bounds.ts # Numeric bounds shared by Zod schemas + engines
|
|
200
|
+
│ ├── engines/
|
|
201
|
+
│ │ ├── mortgage.ts # Pure math + ENGINE_VERSION
|
|
202
|
+
│ │ ├── compoundInterest.ts # Pure math + ENGINE_VERSION
|
|
203
|
+
│ │ ├── retirement401k.ts # Pure math + ENGINE_VERSION (S136)
|
|
204
|
+
│ │ ├── socialSecurity.ts # Pure math + ENGINE_VERSION (S136)
|
|
205
|
+
│ │ ├── paycheck.ts # Pure math + ENGINE_VERSION (S136)
|
|
206
|
+
│ │ └── data/ # Self-contained data subset (S136)
|
|
207
|
+
│ │ ├── ssa.ts # SSA bend points + wage base
|
|
208
|
+
│ │ ├── irs2026.ts # IRS 2026 401(k) limits
|
|
209
|
+
│ │ └── federalTax.ts # 2026 federal brackets/standard ded/FICA
|
|
210
|
+
│ ├── tools/
|
|
211
|
+
│ │ ├── mortgage.ts
|
|
212
|
+
│ │ ├── compoundInterest.ts
|
|
213
|
+
│ │ ├── retirement401k.ts # (S136)
|
|
214
|
+
│ │ ├── socialSecurity.ts # (S136)
|
|
215
|
+
│ │ └── paycheck.ts # (S136)
|
|
216
|
+
│ └── util/zod-to-json-schema.ts
|
|
217
|
+
└── test/
|
|
218
|
+
├── envelope.test.ts # Envelope contract tests
|
|
219
|
+
└── parity/
|
|
220
|
+
├── mortgage.test.ts # parity + envelope checks
|
|
221
|
+
├── compoundInterest.test.ts # parity + envelope checks
|
|
222
|
+
├── retirement401k.test.ts # 5 parity + envelope checks (S136)
|
|
223
|
+
├── socialSecurity.test.ts # 5 parity + envelope checks (S136)
|
|
224
|
+
└── paycheck.test.ts # 5 parity + envelope checks (S136)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Engines are pure synchronous TypeScript ports of the corresponding browser-side calculator JS at `site/src/pages/<calculator>/<calculator>.js` (mortgage, compound-interest, 401k) and `site/src/utils/<x>-engine.js` (Social Security, paycheck). The site files are not imported directly (they mix DOM bindings with math, and npm consumers cannot reach `site/src/`); parity tests guard that the lift remains numerically identical. Where the engines depend on regulatory data (IRS limits, SSA bend points, federal tax brackets), a curated subset is mirrored in `src/engines/data/` and updated in lockstep with the site source.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Versioning
|
|
232
|
+
|
|
233
|
+
- **`@markcolabs/mcp` SemVer**: package version. New tool = minor; renamed tool = major.
|
|
234
|
+
- **Per-engine `ENGINE_VERSION`**: independent SemVer per engine module. Bumps when math changes.
|
|
235
|
+
- **`methodology.version`**: ISO date of the methodology document's `last-modified` field (per ADR-0035).
|
|
236
|
+
|
|
237
|
+
`engineVersion` and `methodology.version` are **independent** — callers should not assume they move in lockstep.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## What's next (post-S136)
|
|
242
|
+
|
|
243
|
+
1. Methodology resources `dc://methodologies/<calculator>` populated from the
|
|
244
|
+
`.md` companions (ADR-0033).
|
|
245
|
+
2. The `plan-retirement` prompt template (O5-KR2).
|
|
246
|
+
3. Per-state withholding tables for the paycheck tool (replace v0.2.0's flat
|
|
247
|
+
5% estimate with bracket-accurate state math).
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## References
|
|
252
|
+
|
|
253
|
+
- ADR-0039 — MCP Tool Contract & Calc-Engine Lift
|
|
254
|
+
- ADR-0033 — Markdown Companion Strategy (powers `methodology.url`)
|
|
255
|
+
- ADR-0035 — JSON-LD `dateModified` Propagation (powers `methodology.version`)
|
|
256
|
+
- ADR-0038 — Centralized Shared-Data Architecture (regulatory constants source)
|
|
257
|
+
- P12 OKR O5 — AI-Native Distribution
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
MIT. Markcolabs LLC.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical YMYL disclaimer — single source of truth.
|
|
3
|
+
*
|
|
4
|
+
* Per ADR-0039 § 3 and § Implementation Notes / "YMYL disclaimer canonicalization":
|
|
5
|
+
* - Every ToolResult.disclaimer field embeds this exact string.
|
|
6
|
+
* - The same string is exposed as the `dc://disclaimers/ymyl` MCP resource.
|
|
7
|
+
* - Tools do NOT author their own disclaimers. All MCP responses use this constant.
|
|
8
|
+
*
|
|
9
|
+
* Authoring is owned by Content. Updates here propagate to every tool response.
|
|
10
|
+
*/
|
|
11
|
+
export declare const YMYL_DISCLAIMER: string;
|
|
12
|
+
/**
|
|
13
|
+
* MCP resource URI under which the disclaimer is exposed (O5-KR2).
|
|
14
|
+
*/
|
|
15
|
+
export declare const YMYL_DISCLAIMER_URI = "dc://disclaimers/ymyl";
|
|
16
|
+
//# sourceMappingURL=ymyl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ymyl.d.ts","sourceRoot":"","sources":["../../src/disclaimers/ymyl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,QAKqE,CAAC;AAElG;;GAEG;AACH,eAAO,MAAM,mBAAmB,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical YMYL disclaimer — single source of truth.
|
|
3
|
+
*
|
|
4
|
+
* Per ADR-0039 § 3 and § Implementation Notes / "YMYL disclaimer canonicalization":
|
|
5
|
+
* - Every ToolResult.disclaimer field embeds this exact string.
|
|
6
|
+
* - The same string is exposed as the `dc://disclaimers/ymyl` MCP resource.
|
|
7
|
+
* - Tools do NOT author their own disclaimers. All MCP responses use this constant.
|
|
8
|
+
*
|
|
9
|
+
* Authoring is owned by Content. Updates here propagate to every tool response.
|
|
10
|
+
*/
|
|
11
|
+
export const YMYL_DISCLAIMER = "Estimates only — for educational purposes. Results are computed in USD using deterministic " +
|
|
12
|
+
"formulas and the inputs you provided. They do not constitute financial, tax, legal, or " +
|
|
13
|
+
"investment advice. Actual rates, fees, taxes, and outcomes vary by lender, jurisdiction, " +
|
|
14
|
+
"and personal circumstances. Verify with a licensed professional before making financial " +
|
|
15
|
+
"decisions. Source: digitalcalculator.info — see methodology link for formula and assumptions.";
|
|
16
|
+
/**
|
|
17
|
+
* MCP resource URI under which the disclaimer is exposed (O5-KR2).
|
|
18
|
+
*/
|
|
19
|
+
export const YMYL_DISCLAIMER_URI = "dc://disclaimers/ymyl";
|
|
20
|
+
//# sourceMappingURL=ymyl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ymyl.js","sourceRoot":"","sources":["../../src/disclaimers/ymyl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAC1B,6FAA6F;IAC7F,yFAAyF;IACzF,2FAA2F;IAC3F,0FAA0F;IAC1F,+FAA+F,CAAC;AAElG;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compound-interest engine — lifted from
|
|
3
|
+
* site/src/pages/compound-interest-calculator/compound-interest-calculator.js
|
|
4
|
+
* (function `calculateFutureValue`).
|
|
5
|
+
*
|
|
6
|
+
* Per ADR-0039 § 5: pure synchronous functions, ENGINE_VERSION constant,
|
|
7
|
+
* parity test against the site source as the gate.
|
|
8
|
+
*
|
|
9
|
+
* Math reference:
|
|
10
|
+
* FV_principal = P * (1 + r/n)^(nt)
|
|
11
|
+
* FV_contributions = PMT_per_period * [((1 + r/n)^(nt) - 1) / (r/n)] (if r > 0)
|
|
12
|
+
* FV_contributions = PMT_per_period * (n * t) (if r == 0)
|
|
13
|
+
* where:
|
|
14
|
+
* P = initial principal
|
|
15
|
+
* PMT_per_period = monthlyContribution * (12 / n)
|
|
16
|
+
* r = annual rate as decimal (e.g., 0.07 for 7%)
|
|
17
|
+
* n = compounding periods per year
|
|
18
|
+
* t = years
|
|
19
|
+
*
|
|
20
|
+
* The engine accepts the rate as a percent and compounding as a label
|
|
21
|
+
* (per ADR-0039 § 2 Percent-suffix convention + sprint prompt enum).
|
|
22
|
+
*/
|
|
23
|
+
import { type CompoundingFrequencyLabel } from "../shared/bounds.js";
|
|
24
|
+
/**
|
|
25
|
+
* SemVer of the compound-interest engine math. Bumps when math changes OR when
|
|
26
|
+
* the package's overall surface area changes (S136 batch bump).
|
|
27
|
+
* - 0.1.0: initial v1 lift from compound-interest-calculator.js (Sprint 135 Item 5).
|
|
28
|
+
* - 0.2.0: minor batch bump on S136 (no math change here; package surface grew
|
|
29
|
+
* from 2 → 5 engines).
|
|
30
|
+
*/
|
|
31
|
+
export declare const ENGINE_VERSION = "0.2.0";
|
|
32
|
+
/**
|
|
33
|
+
* Inputs to the compound-interest future-value engine.
|
|
34
|
+
*
|
|
35
|
+
* Per ADR-0039 § 2:
|
|
36
|
+
* - Monetary fields are bare USD numbers.
|
|
37
|
+
* - Percentage fields use whole-number-percent units (e.g., 7 for 7%).
|
|
38
|
+
* - Optional fields default to 0 inside the engine.
|
|
39
|
+
*/
|
|
40
|
+
export interface CompoundInterestFutureValueInput {
|
|
41
|
+
/** Initial principal in USD. */
|
|
42
|
+
principal: number;
|
|
43
|
+
/** Annual interest rate as whole-number percent (e.g., 7 for 7%). */
|
|
44
|
+
annualRatePercent: number;
|
|
45
|
+
/** Investment period in years. May be 0 (returns principal alone). */
|
|
46
|
+
years: number;
|
|
47
|
+
/** Compounding frequency label. */
|
|
48
|
+
compoundingFrequency: CompoundingFrequencyLabel;
|
|
49
|
+
/** Monthly contribution in USD. Optional — defaults to 0. */
|
|
50
|
+
monthlyContribution?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Result payload (what goes inside ToolResult.result).
|
|
54
|
+
*/
|
|
55
|
+
export interface CompoundInterestFutureValueResult {
|
|
56
|
+
/** Future value (principal + contributions + interest), in USD. */
|
|
57
|
+
futureValue: number;
|
|
58
|
+
/** Total contributed (principal + sum of monthly contributions over the period), in USD. */
|
|
59
|
+
totalContributions: number;
|
|
60
|
+
/** Interest earned (futureValue - totalContributions), in USD. */
|
|
61
|
+
interestEarned: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Compute the future value of a compound-interest investment with optional
|
|
65
|
+
* regular monthly contributions.
|
|
66
|
+
*
|
|
67
|
+
* 1-to-1 port of site/src/pages/compound-interest-calculator/compound-interest-calculator.js
|
|
68
|
+
* function `calculateFutureValue`. Site uses `annualRate` as decimal; this engine
|
|
69
|
+
* accepts whole-number percent and converts internally so the contract is
|
|
70
|
+
* Percent-suffix consistent (ADR-0039).
|
|
71
|
+
*/
|
|
72
|
+
export declare function futureValue(input: CompoundInterestFutureValueInput): CompoundInterestFutureValueResult;
|
|
73
|
+
//# sourceMappingURL=compoundInterest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compoundInterest.d.ts","sourceRoot":"","sources":["../../src/engines/compoundInterest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,qBAAqB,CAAC;AAE7B;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,WAAW,gCAAgC;IAC/C,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,oBAAoB,EAAE,yBAAyB,CAAC;IAChD,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,iCAAiC;IAChD,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,4FAA4F;IAC5F,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,gCAAgC,GACtC,iCAAiC,CAyCnC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compound-interest engine — lifted from
|
|
3
|
+
* site/src/pages/compound-interest-calculator/compound-interest-calculator.js
|
|
4
|
+
* (function `calculateFutureValue`).
|
|
5
|
+
*
|
|
6
|
+
* Per ADR-0039 § 5: pure synchronous functions, ENGINE_VERSION constant,
|
|
7
|
+
* parity test against the site source as the gate.
|
|
8
|
+
*
|
|
9
|
+
* Math reference:
|
|
10
|
+
* FV_principal = P * (1 + r/n)^(nt)
|
|
11
|
+
* FV_contributions = PMT_per_period * [((1 + r/n)^(nt) - 1) / (r/n)] (if r > 0)
|
|
12
|
+
* FV_contributions = PMT_per_period * (n * t) (if r == 0)
|
|
13
|
+
* where:
|
|
14
|
+
* P = initial principal
|
|
15
|
+
* PMT_per_period = monthlyContribution * (12 / n)
|
|
16
|
+
* r = annual rate as decimal (e.g., 0.07 for 7%)
|
|
17
|
+
* n = compounding periods per year
|
|
18
|
+
* t = years
|
|
19
|
+
*
|
|
20
|
+
* The engine accepts the rate as a percent and compounding as a label
|
|
21
|
+
* (per ADR-0039 § 2 Percent-suffix convention + sprint prompt enum).
|
|
22
|
+
*/
|
|
23
|
+
import { COMPOUNDING_FREQUENCY, } from "../shared/bounds.js";
|
|
24
|
+
/**
|
|
25
|
+
* SemVer of the compound-interest engine math. Bumps when math changes OR when
|
|
26
|
+
* the package's overall surface area changes (S136 batch bump).
|
|
27
|
+
* - 0.1.0: initial v1 lift from compound-interest-calculator.js (Sprint 135 Item 5).
|
|
28
|
+
* - 0.2.0: minor batch bump on S136 (no math change here; package surface grew
|
|
29
|
+
* from 2 → 5 engines).
|
|
30
|
+
*/
|
|
31
|
+
export const ENGINE_VERSION = "0.2.0";
|
|
32
|
+
/**
|
|
33
|
+
* Compute the future value of a compound-interest investment with optional
|
|
34
|
+
* regular monthly contributions.
|
|
35
|
+
*
|
|
36
|
+
* 1-to-1 port of site/src/pages/compound-interest-calculator/compound-interest-calculator.js
|
|
37
|
+
* function `calculateFutureValue`. Site uses `annualRate` as decimal; this engine
|
|
38
|
+
* accepts whole-number percent and converts internally so the contract is
|
|
39
|
+
* Percent-suffix consistent (ADR-0039).
|
|
40
|
+
*/
|
|
41
|
+
export function futureValue(input) {
|
|
42
|
+
const { principal, annualRatePercent, years, compoundingFrequency, monthlyContribution = 0, } = input;
|
|
43
|
+
// Percent → decimal at the engine boundary.
|
|
44
|
+
const r = annualRatePercent / 100;
|
|
45
|
+
const n = COMPOUNDING_FREQUENCY[compoundingFrequency];
|
|
46
|
+
const t = years;
|
|
47
|
+
const periods = n * t;
|
|
48
|
+
const periodicRate = r / n;
|
|
49
|
+
// FV of principal.
|
|
50
|
+
const fvPrincipal = principal * Math.pow(1 + periodicRate, periods);
|
|
51
|
+
// FV of regular contributions (annuity-due-like, contributions split per period).
|
|
52
|
+
const contributionPerPeriod = monthlyContribution * (12 / n);
|
|
53
|
+
let fvContributions = 0;
|
|
54
|
+
if (periodicRate > 0 && contributionPerPeriod > 0) {
|
|
55
|
+
fvContributions =
|
|
56
|
+
contributionPerPeriod *
|
|
57
|
+
((Math.pow(1 + periodicRate, periods) - 1) / periodicRate);
|
|
58
|
+
}
|
|
59
|
+
else if (contributionPerPeriod > 0) {
|
|
60
|
+
// 0% rate: contributions just sum.
|
|
61
|
+
fvContributions = contributionPerPeriod * periods;
|
|
62
|
+
}
|
|
63
|
+
const futureValueTotal = fvPrincipal + fvContributions;
|
|
64
|
+
const totalContributions = principal + monthlyContribution * 12 * t;
|
|
65
|
+
const interestEarned = futureValueTotal - totalContributions;
|
|
66
|
+
return {
|
|
67
|
+
futureValue: futureValueTotal,
|
|
68
|
+
totalContributions,
|
|
69
|
+
interestEarned,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=compoundInterest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compoundInterest.js","sourceRoot":"","sources":["../../src/engines/compoundInterest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EACL,qBAAqB,GAEtB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAmCtC;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CACzB,KAAuC;IAEvC,MAAM,EACJ,SAAS,EACT,iBAAiB,EACjB,KAAK,EACL,oBAAoB,EACpB,mBAAmB,GAAG,CAAC,GACxB,GAAG,KAAK,CAAC;IAEV,4CAA4C;IAC5C,MAAM,CAAC,GAAG,iBAAiB,GAAG,GAAG,CAAC;IAClC,MAAM,CAAC,GAAG,qBAAqB,CAAC,oBAAoB,CAAC,CAAC;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC;IAEhB,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;IACtB,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC;IAE3B,mBAAmB;IACnB,MAAM,WAAW,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,OAAO,CAAC,CAAC;IAEpE,kFAAkF;IAClF,MAAM,qBAAqB,GAAG,mBAAmB,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7D,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,YAAY,GAAG,CAAC,IAAI,qBAAqB,GAAG,CAAC,EAAE,CAAC;QAClD,eAAe;YACb,qBAAqB;gBACrB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC;IAC/D,CAAC;SAAM,IAAI,qBAAqB,GAAG,CAAC,EAAE,CAAC;QACrC,mCAAmC;QACnC,eAAe,GAAG,qBAAqB,GAAG,OAAO,CAAC;IACpD,CAAC;IAED,MAAM,gBAAgB,GAAG,WAAW,GAAG,eAAe,CAAC;IACvD,MAAM,kBAAkB,GAAG,SAAS,GAAG,mBAAmB,GAAG,EAAE,GAAG,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;IAE7D,OAAO;QACL,WAAW,EAAE,gBAAgB;QAC7B,kBAAkB;QAClB,cAAc;KACf,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained 2026 federal tax data subset for the @markcolabs/mcp
|
|
3
|
+
* package's paycheck engine.
|
|
4
|
+
*
|
|
5
|
+
* Mirrored from site/src/data/annual-limits.js. See engines/data/ssa.ts for the
|
|
6
|
+
* full rationale on the mirror pattern (npm consumers cannot reach site/src/).
|
|
7
|
+
*
|
|
8
|
+
* Filing status keys mirror the paycheck engine's camelCase convention:
|
|
9
|
+
* "single" | "married" | "marriedSeparate" | "headOfHousehold"
|
|
10
|
+
*
|
|
11
|
+
* Source of truth: IRS Rev. Proc. 2025-32 (2026 inflation adjustments).
|
|
12
|
+
* Last verified: 2026-05-09.
|
|
13
|
+
*/
|
|
14
|
+
import { SS_WAGE_BASE } from "./ssa.js";
|
|
15
|
+
export type FilingStatus = "single" | "married" | "marriedSeparate" | "headOfHousehold";
|
|
16
|
+
/** FICA statutory rates (unchanged since 1990 / ACA 2013). */
|
|
17
|
+
export declare const FICA_RATES: {
|
|
18
|
+
readonly socialSecurityRate: 0.062;
|
|
19
|
+
readonly medicareRate: 0.0145;
|
|
20
|
+
readonly additionalMedicareRate: 0.009;
|
|
21
|
+
};
|
|
22
|
+
/** Additional Medicare Tax 0.9% kicks in above these wage thresholds (filing-status keyed). */
|
|
23
|
+
export declare const ADDITIONAL_MEDICARE_THRESHOLDS_2026: Record<FilingStatus, number>;
|
|
24
|
+
/** 2026 standard deductions (IRS Rev. Proc. 2025-32). */
|
|
25
|
+
export declare const STANDARD_DEDUCTIONS_2026: Record<FilingStatus, number>;
|
|
26
|
+
/** Tax bracket entry. `max: null` indicates the top open-ended bracket. */
|
|
27
|
+
export interface TaxBracket {
|
|
28
|
+
min: number;
|
|
29
|
+
max: number | null;
|
|
30
|
+
rate: number;
|
|
31
|
+
/** Cumulative tax at this bracket's floor (Percentage Method). */
|
|
32
|
+
baseTax: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 2026 federal tax brackets (IRS Rev. Proc. 2025-32; verified AL-2026-001 S134).
|
|
36
|
+
* Filing-status keyed; values match site/src/data/annual-limits.js TAX_BRACKETS[2026].
|
|
37
|
+
*/
|
|
38
|
+
export declare const FEDERAL_TAX_BRACKETS_2026: Record<FilingStatus, TaxBracket[]>;
|
|
39
|
+
/** Pay periods per year. Matches site/src/utils/paycheck-tax-engine.js PAY_PERIODS. */
|
|
40
|
+
export declare const PAY_PERIODS_PER_YEAR: Record<"weekly" | "biweekly" | "semimonthly" | "monthly" | "quarterly" | "annual", number>;
|
|
41
|
+
export type PayFrequencyLabel = keyof typeof PAY_PERIODS_PER_YEAR;
|
|
42
|
+
/** US states with no income tax (paycheck engine NO_TAX_STATES). */
|
|
43
|
+
export declare const NO_TAX_STATES: readonly ["AK", "FL", "NV", "NH", "SD", "TN", "TX", "WA", "WY"];
|
|
44
|
+
export type NoTaxStateCode = (typeof NO_TAX_STATES)[number];
|
|
45
|
+
/** Re-export SS wage base for paycheck engine (FICA SS cap). */
|
|
46
|
+
export { SS_WAGE_BASE };
|
|
47
|
+
//# sourceMappingURL=federalTax.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"federalTax.d.ts","sourceRoot":"","sources":["../../../src/engines/data/federalTax.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAExF,8DAA8D;AAC9D,eAAO,MAAM,UAAU;;;;CAIb,CAAC;AAEX,+FAA+F;AAC/F,eAAO,MAAM,mCAAmC,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAK5E,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAKjE,CAAC;AAEF,2EAA2E;AAC3E,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;CACjB;AAgBD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,YAAY,EAAE,UAAU,EAAE,CAqCxE,CAAC;AAEF,uFAAuF;AACvF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CACvC,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,EAC1E,MAAM,CAQP,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,oBAAoB,CAAC;AAElE,oEAAoE;AACpE,eAAO,MAAM,aAAa,iEAUhB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,gEAAgE;AAChE,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained 2026 federal tax data subset for the @markcolabs/mcp
|
|
3
|
+
* package's paycheck engine.
|
|
4
|
+
*
|
|
5
|
+
* Mirrored from site/src/data/annual-limits.js. See engines/data/ssa.ts for the
|
|
6
|
+
* full rationale on the mirror pattern (npm consumers cannot reach site/src/).
|
|
7
|
+
*
|
|
8
|
+
* Filing status keys mirror the paycheck engine's camelCase convention:
|
|
9
|
+
* "single" | "married" | "marriedSeparate" | "headOfHousehold"
|
|
10
|
+
*
|
|
11
|
+
* Source of truth: IRS Rev. Proc. 2025-32 (2026 inflation adjustments).
|
|
12
|
+
* Last verified: 2026-05-09.
|
|
13
|
+
*/
|
|
14
|
+
import { SS_WAGE_BASE } from "./ssa.js";
|
|
15
|
+
/** FICA statutory rates (unchanged since 1990 / ACA 2013). */
|
|
16
|
+
export const FICA_RATES = {
|
|
17
|
+
socialSecurityRate: 0.062,
|
|
18
|
+
medicareRate: 0.0145,
|
|
19
|
+
additionalMedicareRate: 0.009,
|
|
20
|
+
};
|
|
21
|
+
/** Additional Medicare Tax 0.9% kicks in above these wage thresholds (filing-status keyed). */
|
|
22
|
+
export const ADDITIONAL_MEDICARE_THRESHOLDS_2026 = {
|
|
23
|
+
single: 200_000,
|
|
24
|
+
married: 250_000,
|
|
25
|
+
marriedSeparate: 125_000,
|
|
26
|
+
headOfHousehold: 200_000,
|
|
27
|
+
};
|
|
28
|
+
/** 2026 standard deductions (IRS Rev. Proc. 2025-32). */
|
|
29
|
+
export const STANDARD_DEDUCTIONS_2026 = {
|
|
30
|
+
single: 15_750,
|
|
31
|
+
married: 31_500,
|
|
32
|
+
marriedSeparate: 15_750,
|
|
33
|
+
headOfHousehold: 23_625,
|
|
34
|
+
};
|
|
35
|
+
/** Build cumulative `baseTax` for each bracket (used by the Percentage Method). */
|
|
36
|
+
function withBaseTax(brackets) {
|
|
37
|
+
let cumulative = 0;
|
|
38
|
+
return brackets.map((b) => {
|
|
39
|
+
const baseTax = cumulative;
|
|
40
|
+
if (b.max !== null) {
|
|
41
|
+
cumulative += (b.max - b.min) * b.rate;
|
|
42
|
+
}
|
|
43
|
+
return { min: b.min, max: b.max, rate: b.rate, baseTax };
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 2026 federal tax brackets (IRS Rev. Proc. 2025-32; verified AL-2026-001 S134).
|
|
48
|
+
* Filing-status keyed; values match site/src/data/annual-limits.js TAX_BRACKETS[2026].
|
|
49
|
+
*/
|
|
50
|
+
export const FEDERAL_TAX_BRACKETS_2026 = {
|
|
51
|
+
single: withBaseTax([
|
|
52
|
+
{ min: 0, max: 12_400, rate: 0.10 },
|
|
53
|
+
{ min: 12_400, max: 50_400, rate: 0.12 },
|
|
54
|
+
{ min: 50_400, max: 105_700, rate: 0.22 },
|
|
55
|
+
{ min: 105_700, max: 201_775, rate: 0.24 },
|
|
56
|
+
{ min: 201_775, max: 256_225, rate: 0.32 },
|
|
57
|
+
{ min: 256_225, max: 640_600, rate: 0.35 },
|
|
58
|
+
{ min: 640_600, max: null, rate: 0.37 },
|
|
59
|
+
]),
|
|
60
|
+
married: withBaseTax([
|
|
61
|
+
{ min: 0, max: 24_800, rate: 0.10 },
|
|
62
|
+
{ min: 24_800, max: 100_800, rate: 0.12 },
|
|
63
|
+
{ min: 100_800, max: 211_400, rate: 0.22 },
|
|
64
|
+
{ min: 211_400, max: 403_550, rate: 0.24 },
|
|
65
|
+
{ min: 403_550, max: 512_450, rate: 0.32 },
|
|
66
|
+
{ min: 512_450, max: 768_700, rate: 0.35 },
|
|
67
|
+
{ min: 768_700, max: null, rate: 0.37 },
|
|
68
|
+
]),
|
|
69
|
+
marriedSeparate: withBaseTax([
|
|
70
|
+
{ min: 0, max: 12_400, rate: 0.10 },
|
|
71
|
+
{ min: 12_400, max: 50_400, rate: 0.12 },
|
|
72
|
+
{ min: 50_400, max: 105_700, rate: 0.22 },
|
|
73
|
+
{ min: 105_700, max: 201_775, rate: 0.24 },
|
|
74
|
+
{ min: 201_775, max: 256_225, rate: 0.32 },
|
|
75
|
+
{ min: 256_225, max: 384_350, rate: 0.35 },
|
|
76
|
+
{ min: 384_350, max: null, rate: 0.37 },
|
|
77
|
+
]),
|
|
78
|
+
headOfHousehold: withBaseTax([
|
|
79
|
+
{ min: 0, max: 17_700, rate: 0.10 },
|
|
80
|
+
{ min: 17_700, max: 67_450, rate: 0.12 },
|
|
81
|
+
{ min: 67_450, max: 105_700, rate: 0.22 },
|
|
82
|
+
{ min: 105_700, max: 201_775, rate: 0.24 },
|
|
83
|
+
{ min: 201_775, max: 256_200, rate: 0.32 },
|
|
84
|
+
{ min: 256_200, max: 640_600, rate: 0.35 },
|
|
85
|
+
{ min: 640_600, max: null, rate: 0.37 },
|
|
86
|
+
]),
|
|
87
|
+
};
|
|
88
|
+
/** Pay periods per year. Matches site/src/utils/paycheck-tax-engine.js PAY_PERIODS. */
|
|
89
|
+
export const PAY_PERIODS_PER_YEAR = {
|
|
90
|
+
weekly: 52,
|
|
91
|
+
biweekly: 26,
|
|
92
|
+
semimonthly: 24,
|
|
93
|
+
monthly: 12,
|
|
94
|
+
quarterly: 4,
|
|
95
|
+
annual: 1,
|
|
96
|
+
};
|
|
97
|
+
/** US states with no income tax (paycheck engine NO_TAX_STATES). */
|
|
98
|
+
export const NO_TAX_STATES = [
|
|
99
|
+
"AK",
|
|
100
|
+
"FL",
|
|
101
|
+
"NV",
|
|
102
|
+
"NH",
|
|
103
|
+
"SD",
|
|
104
|
+
"TN",
|
|
105
|
+
"TX",
|
|
106
|
+
"WA",
|
|
107
|
+
"WY",
|
|
108
|
+
];
|
|
109
|
+
/** Re-export SS wage base for paycheck engine (FICA SS cap). */
|
|
110
|
+
export { SS_WAGE_BASE };
|
|
111
|
+
//# sourceMappingURL=federalTax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"federalTax.js","sourceRoot":"","sources":["../../../src/engines/data/federalTax.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained 2026 IRS retirement-plan limits subset for the MCP package's
|
|
3
|
+
* 401(k) projection engine.
|
|
4
|
+
*
|
|
5
|
+
* Mirrored from site/src/data/annual-limits.js LIMITS_401K_2026. See
|
|
6
|
+
* engines/data/ssa.ts for full rationale on the mirror pattern.
|
|
7
|
+
*
|
|
8
|
+
* Source: IRS Notice 2025-67 (2026 retirement-plan limits) +
|
|
9
|
+
* SECURE 2.0 Act §109 (super catch-up provision for ages 60-63).
|
|
10
|
+
* Last verified: 2026-05-09.
|
|
11
|
+
*/
|
|
12
|
+
export declare const LIMITS_401K_2026: {
|
|
13
|
+
/** Base employee deferral limit. */
|
|
14
|
+
readonly base: 24500;
|
|
15
|
+
/** Regular catch-up amount for ages 50-59 or 64+. */
|
|
16
|
+
readonly catchUp: 8000;
|
|
17
|
+
/** Super catch-up amount for ages 60-63 (SECURE 2.0). */
|
|
18
|
+
readonly superCatchUp: 11250;
|
|
19
|
+
/** Total deferral limit with regular catch-up. */
|
|
20
|
+
readonly totalWithCatchUp: 32500;
|
|
21
|
+
/** Total deferral limit with super catch-up. */
|
|
22
|
+
readonly totalWithSuperCatchUp: 35750;
|
|
23
|
+
/** Minimum age for any catch-up. */
|
|
24
|
+
readonly catchUpAge: 50;
|
|
25
|
+
/** Start of super catch-up window. */
|
|
26
|
+
readonly superCatchUpAgeStart: 60;
|
|
27
|
+
/** End of super catch-up window. */
|
|
28
|
+
readonly superCatchUpAgeEnd: 63;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=irs2026.d.ts.map
|