@invaro/opentax 0.1.0 → 0.2.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.
Files changed (69) hide show
  1. package/README.md +64 -0
  2. package/bundle/http.js +37595 -0
  3. package/bundle/index.js +36289 -0
  4. package/bundle/main.js +45281 -0
  5. package/package.json +16 -14
  6. package/dist/documents.d.ts +0 -177
  7. package/dist/documents.d.ts.map +0 -1
  8. package/dist/documents.js +0 -246
  9. package/dist/documents.js.map +0 -1
  10. package/dist/hosted-bundle.d.ts +0 -8
  11. package/dist/hosted-bundle.d.ts.map +0 -1
  12. package/dist/hosted-bundle.js +0 -8
  13. package/dist/hosted-bundle.js.map +0 -1
  14. package/dist/http.d.ts +0 -15
  15. package/dist/http.d.ts.map +0 -1
  16. package/dist/http.js +0 -90
  17. package/dist/http.js.map +0 -1
  18. package/dist/index.d.ts +0 -9
  19. package/dist/index.d.ts.map +0 -1
  20. package/dist/index.js +0 -13
  21. package/dist/index.js.map +0 -1
  22. package/dist/schema.d.ts +0 -60
  23. package/dist/schema.d.ts.map +0 -1
  24. package/dist/schema.js +0 -467
  25. package/dist/schema.js.map +0 -1
  26. package/dist/server.d.ts +0 -14
  27. package/dist/server.d.ts.map +0 -1
  28. package/dist/server.js +0 -509
  29. package/dist/server.js.map +0 -1
  30. package/dist/state-return/ca.d.ts +0 -3
  31. package/dist/state-return/ca.d.ts.map +0 -1
  32. package/dist/state-return/ca.js +0 -108
  33. package/dist/state-return/ca.js.map +0 -1
  34. package/dist/state-return/il.d.ts +0 -3
  35. package/dist/state-return/il.d.ts.map +0 -1
  36. package/dist/state-return/il.js +0 -64
  37. package/dist/state-return/il.js.map +0 -1
  38. package/dist/state-return/index.d.ts +0 -8
  39. package/dist/state-return/index.d.ts.map +0 -1
  40. package/dist/state-return/index.js +0 -38
  41. package/dist/state-return/index.js.map +0 -1
  42. package/dist/state-return/money.d.ts +0 -10
  43. package/dist/state-return/money.d.ts.map +0 -1
  44. package/dist/state-return/money.js +0 -18
  45. package/dist/state-return/money.js.map +0 -1
  46. package/dist/state-return/ny.d.ts +0 -3
  47. package/dist/state-return/ny.d.ts.map +0 -1
  48. package/dist/state-return/ny.js +0 -59
  49. package/dist/state-return/ny.js.map +0 -1
  50. package/dist/state-return/shape.d.ts +0 -80
  51. package/dist/state-return/shape.d.ts.map +0 -1
  52. package/dist/state-return/shape.js +0 -97
  53. package/dist/state-return/shape.js.map +0 -1
  54. package/dist/state-return/types.d.ts +0 -17
  55. package/dist/state-return/types.d.ts.map +0 -1
  56. package/dist/state-return/types.js +0 -6
  57. package/dist/state-return/types.js.map +0 -1
  58. package/dist/state-return/va-worksheets.d.ts +0 -70
  59. package/dist/state-return/va-worksheets.d.ts.map +0 -1
  60. package/dist/state-return/va-worksheets.js +0 -116
  61. package/dist/state-return/va-worksheets.js.map +0 -1
  62. package/dist/state-return/va.d.ts +0 -3
  63. package/dist/state-return/va.d.ts.map +0 -1
  64. package/dist/state-return/va.js +0 -130
  65. package/dist/state-return/va.js.map +0 -1
  66. package/dist/state-return.d.ts +0 -4
  67. package/dist/state-return.d.ts.map +0 -1
  68. package/dist/state-return.js +0 -3
  69. package/dist/state-return.js.map +0 -1
package/package.json CHANGED
@@ -1,28 +1,30 @@
1
1
  {
2
2
  "name": "@invaro/opentax",
3
- "version": "0.1.0",
4
- "description": "MCP server exposing the opentax engine to AI agents: calculate, verify claims, find cliffs — every answer cited and provable",
3
+ "version": "0.2.0",
4
+ "description": "The verifiable US tax oracle: MCP server for AI agents + full CLI in one self-contained package — every answer cited to statute and machine-checkable",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "bin": {
8
- "opentax-mcp": "./dist/index.js",
9
- "opentax-mcp-http": "./dist/http.js"
8
+ "opentax": "./bundle/main.js",
9
+ "opentax-mcp": "./bundle/index.js",
10
+ "opentax-mcp-http": "./bundle/http.js"
10
11
  },
11
- "main": "./dist/index.js",
12
+ "main": "./bundle/main.js",
12
13
  "files": [
13
- "dist"
14
+ "bundle",
15
+ "README.md"
14
16
  ],
15
- "dependencies": {
17
+ "dependencies": {},
18
+ "devDependencies": {
19
+ "@types/node": "^26.1.0",
20
+ "typescript": "^5.8.3",
16
21
  "@modelcontextprotocol/sdk": "^1.12.0",
17
22
  "zod": "^3.24.0",
18
23
  "@invaro/opentax-compose": "0.1.0",
19
- "@invaro/opentax-core": "0.1.0",
24
+ "@invaro/opentax-solve": "0.1.0",
20
25
  "@invaro/opentax-corpus-us-federal": "0.6.0",
21
- "@invaro/opentax-solve": "0.1.0"
22
- },
23
- "devDependencies": {
24
- "@types/node": "^26.1.0",
25
- "typescript": "^5.8.3"
26
+ "@invaro/opentax-core": "0.1.0",
27
+ "@invaro/opentax-cli": "0.1.1"
26
28
  },
27
29
  "repository": {
28
30
  "type": "git",
@@ -49,6 +51,6 @@
49
51
  ],
50
52
  "mcpName": "io.github.invaro/opentax",
51
53
  "scripts": {
52
- "build": "tsc -p tsconfig.json"
54
+ "build": "tsc -p tsconfig.json && esbuild dist/main.js dist/index.js dist/http.js --bundle --platform=node --format=esm --outdir=bundle --banner:js=\"import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);\" --log-level=warning"
53
55
  }
54
56
  }
@@ -1,177 +0,0 @@
1
- /**
2
- * Document compiler — deterministic transcription-to-facts.
3
- *
4
- * Every agent-variance failure in the benchmark rounds happened where the
5
- * MCP accepted a pre-digested JUDGMENT instead of a raw document value: a
6
- * dependent pre-classified from a checkbox label, a Form 8959 Part IV
7
- * reconciliation left to mental arithmetic, a penalty decided from a payer's
8
- * box code, a documented amount deleted as "anomalous". This module moves
9
- * those derivations into code: agents transcribe boxes and dates; the
10
- * compiler classifies, sums, reconciles, and DISCLOSES — and it throws
11
- * loudly if the same value arrives both raw and pre-digested.
12
- */
13
- import { z } from "zod";
14
- export declare const documentsShape: z.ZodObject<{
15
- taxpayerDateOfBirth: z.ZodOptional<z.ZodString>;
16
- spouseDateOfBirth: z.ZodOptional<z.ZodString>;
17
- w2s: z.ZodOptional<z.ZodArray<z.ZodObject<{
18
- box1: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
19
- box2: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
20
- box3: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
21
- box5: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
22
- box6: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
23
- box17: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
24
- }, "strict", z.ZodTypeAny, {
25
- box1: string | number;
26
- box2?: string | number | undefined;
27
- box3?: string | number | undefined;
28
- box5?: string | number | undefined;
29
- box6?: string | number | undefined;
30
- box17?: string | number | undefined;
31
- }, {
32
- box1: string | number;
33
- box2?: string | number | undefined;
34
- box3?: string | number | undefined;
35
- box5?: string | number | undefined;
36
- box6?: string | number | undefined;
37
- box17?: string | number | undefined;
38
- }>, "many">>;
39
- f1099rs: z.ZodOptional<z.ZodArray<z.ZodObject<{
40
- box1: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
41
- box2a: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
42
- box4: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
43
- box7: z.ZodString;
44
- iraSepSimple: z.ZodOptional<z.ZodBoolean>;
45
- recipient: z.ZodOptional<z.ZodEnum<["taxpayer", "spouse"]>>;
46
- rolledOver: z.ZodOptional<z.ZodBoolean>;
47
- disabilityBeforeRetirementAge: z.ZodOptional<z.ZodBoolean>;
48
- }, "strict", z.ZodTypeAny, {
49
- box1: string | number;
50
- box2a: string | number;
51
- box7: string;
52
- box4?: string | number | undefined;
53
- iraSepSimple?: boolean | undefined;
54
- recipient?: "taxpayer" | "spouse" | undefined;
55
- rolledOver?: boolean | undefined;
56
- disabilityBeforeRetirementAge?: boolean | undefined;
57
- }, {
58
- box1: string | number;
59
- box2a: string | number;
60
- box7: string;
61
- box4?: string | number | undefined;
62
- iraSepSimple?: boolean | undefined;
63
- recipient?: "taxpayer" | "spouse" | undefined;
64
- rolledOver?: boolean | undefined;
65
- disabilityBeforeRetirementAge?: boolean | undefined;
66
- }>, "many">>;
67
- ssa1099s: z.ZodOptional<z.ZodArray<z.ZodObject<{
68
- box5: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
69
- box6: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
70
- }, "strict", z.ZodTypeAny, {
71
- box5: string | number;
72
- box6?: string | number | undefined;
73
- }, {
74
- box5: string | number;
75
- box6?: string | number | undefined;
76
- }>, "many">>;
77
- dependents: z.ZodOptional<z.ZodArray<z.ZodObject<{
78
- dateOfBirth: z.ZodString;
79
- relationship: z.ZodOptional<z.ZodEnum<["child_or_descendant", "sibling_or_descendant", "parent_or_other_relative"]>>;
80
- isPermanentlyDisabled: z.ZodOptional<z.ZodBoolean>;
81
- isFullTimeStudent: z.ZodOptional<z.ZodBoolean>;
82
- hasRequiredSSN: z.ZodOptional<z.ZodBoolean>;
83
- monthsLivedWithTaxpayer: z.ZodOptional<z.ZodNumber>;
84
- }, "strict", z.ZodTypeAny, {
85
- dateOfBirth: string;
86
- relationship?: "child_or_descendant" | "sibling_or_descendant" | "parent_or_other_relative" | undefined;
87
- isPermanentlyDisabled?: boolean | undefined;
88
- isFullTimeStudent?: boolean | undefined;
89
- hasRequiredSSN?: boolean | undefined;
90
- monthsLivedWithTaxpayer?: number | undefined;
91
- }, {
92
- dateOfBirth: string;
93
- relationship?: "child_or_descendant" | "sibling_or_descendant" | "parent_or_other_relative" | undefined;
94
- isPermanentlyDisabled?: boolean | undefined;
95
- isFullTimeStudent?: boolean | undefined;
96
- hasRequiredSSN?: boolean | undefined;
97
- monthsLivedWithTaxpayer?: number | undefined;
98
- }>, "many">>;
99
- }, "strict", z.ZodTypeAny, {
100
- taxpayerDateOfBirth?: string | undefined;
101
- spouseDateOfBirth?: string | undefined;
102
- w2s?: {
103
- box1: string | number;
104
- box2?: string | number | undefined;
105
- box3?: string | number | undefined;
106
- box5?: string | number | undefined;
107
- box6?: string | number | undefined;
108
- box17?: string | number | undefined;
109
- }[] | undefined;
110
- f1099rs?: {
111
- box1: string | number;
112
- box2a: string | number;
113
- box7: string;
114
- box4?: string | number | undefined;
115
- iraSepSimple?: boolean | undefined;
116
- recipient?: "taxpayer" | "spouse" | undefined;
117
- rolledOver?: boolean | undefined;
118
- disabilityBeforeRetirementAge?: boolean | undefined;
119
- }[] | undefined;
120
- ssa1099s?: {
121
- box5: string | number;
122
- box6?: string | number | undefined;
123
- }[] | undefined;
124
- dependents?: {
125
- dateOfBirth: string;
126
- relationship?: "child_or_descendant" | "sibling_or_descendant" | "parent_or_other_relative" | undefined;
127
- isPermanentlyDisabled?: boolean | undefined;
128
- isFullTimeStudent?: boolean | undefined;
129
- hasRequiredSSN?: boolean | undefined;
130
- monthsLivedWithTaxpayer?: number | undefined;
131
- }[] | undefined;
132
- }, {
133
- taxpayerDateOfBirth?: string | undefined;
134
- spouseDateOfBirth?: string | undefined;
135
- w2s?: {
136
- box1: string | number;
137
- box2?: string | number | undefined;
138
- box3?: string | number | undefined;
139
- box5?: string | number | undefined;
140
- box6?: string | number | undefined;
141
- box17?: string | number | undefined;
142
- }[] | undefined;
143
- f1099rs?: {
144
- box1: string | number;
145
- box2a: string | number;
146
- box7: string;
147
- box4?: string | number | undefined;
148
- iraSepSimple?: boolean | undefined;
149
- recipient?: "taxpayer" | "spouse" | undefined;
150
- rolledOver?: boolean | undefined;
151
- disabilityBeforeRetirementAge?: boolean | undefined;
152
- }[] | undefined;
153
- ssa1099s?: {
154
- box5: string | number;
155
- box6?: string | number | undefined;
156
- }[] | undefined;
157
- dependents?: {
158
- dateOfBirth: string;
159
- relationship?: "child_or_descendant" | "sibling_or_descendant" | "parent_or_other_relative" | undefined;
160
- isPermanentlyDisabled?: boolean | undefined;
161
- isFullTimeStudent?: boolean | undefined;
162
- hasRequiredSSN?: boolean | undefined;
163
- monthsLivedWithTaxpayer?: number | undefined;
164
- }[] | undefined;
165
- }>;
166
- type Docs = z.infer<typeof documentsShape>;
167
- export interface CompiledDocs {
168
- facts: Record<string, unknown>;
169
- notes: string[];
170
- /** Sum of W-2 box 1 in cents — Form 1040 line 1a is W-2 box 1 ONLY; any other
171
- * amount folded into the wages fact (e.g. pre-retirement disability, Pub. 525)
172
- * is line 1h other earned income. */
173
- w2Box1Cents: bigint;
174
- }
175
- export declare function compileDocuments(docs: Docs, asOf: string): CompiledDocs;
176
- export {};
177
- //# sourceMappingURL=documents.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../src/documents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyExB,CAAC;AAEJ,KAAK,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AA4B3C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;yCAEqC;IACrC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAuIvE"}
package/dist/documents.js DELETED
@@ -1,246 +0,0 @@
1
- /**
2
- * Document compiler — deterministic transcription-to-facts.
3
- *
4
- * Every agent-variance failure in the benchmark rounds happened where the
5
- * MCP accepted a pre-digested JUDGMENT instead of a raw document value: a
6
- * dependent pre-classified from a checkbox label, a Form 8959 Part IV
7
- * reconciliation left to mental arithmetic, a penalty decided from a payer's
8
- * box code, a documented amount deleted as "anomalous". This module moves
9
- * those derivations into code: agents transcribe boxes and dates; the
10
- * compiler classifies, sums, reconciles, and DISCLOSES — and it throws
11
- * loudly if the same value arrives both raw and pre-digested.
12
- */
13
- import { z } from "zod";
14
- const usd = z.union([z.number(), z.string()]).describe('dollars, e.g. 50000 or "1234.56"');
15
- const dob = z
16
- .string()
17
- .regex(/^\d{4}-\d{2}-\d{2}$/)
18
- .describe("date of birth, YYYY-MM-DD");
19
- export const documentsShape = z
20
- .object({
21
- taxpayerDateOfBirth: dob
22
- .optional()
23
- .describe("derives age-based facts (65+, 25-64 EITC window, 50/55 catch-ups, 59½ penalty)"),
24
- spouseDateOfBirth: dob.optional(),
25
- w2s: z
26
- .array(z
27
- .object({
28
- box1: usd.describe("wages, tips, other compensation"),
29
- box2: usd.optional().describe("federal income tax withheld"),
30
- box3: usd.optional().describe("social security wages"),
31
- box5: usd.optional().describe("Medicare wages and tips"),
32
- box6: usd.optional().describe("Medicare tax withheld — Part IV excess over 1.45% of box 5 is added to withholding automatically"),
33
- box17: usd.optional().describe("state income tax withheld — surfaced as a SALT note; enter in itemized.stateAndLocalTaxesPaid yourself if itemizing"),
34
- })
35
- .strict())
36
- .optional()
37
- .describe("one entry per W-2, boxes transcribed verbatim"),
38
- f1099rs: z
39
- .array(z
40
- .object({
41
- box1: usd.describe("gross distribution"),
42
- box2a: usd.describe("taxable amount (0 if fully rolled over / converted basis applied via ira8606)"),
43
- box4: usd.optional().describe("federal income tax withheld"),
44
- box7: z.string().describe('distribution code(s), e.g. "1", "7", "4", "G", "3", "C"'),
45
- iraSepSimple: z.boolean().optional().describe("the IRA/SEP/SIMPLE checkbox"),
46
- recipient: z.enum(["taxpayer", "spouse"]).optional().describe("whose distribution (for the age-based penalty test); default taxpayer"),
47
- rolledOver: z.boolean().optional().describe("interview-confirmed full rollover (e.g. 'distributions less rollovers = 0') — excluded from taxable income regardless of box 2a"),
48
- disabilityBeforeRetirementAge: z.boolean().optional().describe("code-3 disability received before minimum retirement age — reported as WAGES (Pub. 525) and counted as § 22 disability income"),
49
- })
50
- .strict())
51
- .optional()
52
- .describe("one entry per 1099-R; routing, penalty, and rollover handling are computed, not judged"),
53
- ssa1099s: z
54
- .array(z
55
- .object({
56
- box5: usd.describe("net benefits (box 5) — includible amount computed by the § 86 0/50/85% formula, not judged here"),
57
- box6: usd.optional().describe("voluntary federal income tax withheld"),
58
- })
59
- .strict())
60
- .optional()
61
- .describe("one entry per SSA-1099 (or RRB-1099 tier-1 equivalent); box 5 sums into socialSecurityBenefits, box 6 into withholding"),
62
- dependents: z
63
- .array(z
64
- .object({
65
- dateOfBirth: dob,
66
- relationship: z
67
- .enum(["child_or_descendant", "sibling_or_descendant", "parent_or_other_relative"])
68
- .optional()
69
- .describe("§ 152(c)(2) lineage: children/grandchildren and siblings/nieces/nephews can be QUALIFYING CHILDREN; a parent or other relative can only be a qualifying RELATIVE (ODC, never CTC/EIC-child). TRANSCRIBE the document's own label: son/daughter/grandchild/foster/sibling/niece → child_or_descendant or sibling_or_descendant; an explicit 'other' relationship on a source form → parent_or_other_relative (never default it back to child lineage). The child_or_descendant default is ONLY for documents that state a child relationship or say nothing at all."),
70
- isPermanentlyDisabled: z.boolean().optional(),
71
- isFullTimeStudent: z.boolean().optional(),
72
- hasRequiredSSN: z.boolean().optional().describe("default true"),
73
- monthsLivedWithTaxpayer: z.number().int().min(0).max(12).optional().describe("default 12"),
74
- })
75
- .strict())
76
- .optional()
77
- .describe("one entry per dependent, RAW facts — CTC vs ODC vs EIC-child vs CDCC classification is computed from the statute's age tests, never from intake checkbox labels"),
78
- })
79
- .strict()
80
- .describe("RAW document transcription (preferred over hand-mapped facts): W-2 boxes, 1099-R boxes/codes, SSA-1099 boxes, dependents' birth dates. SSA-1099s are first-class: box 5 sums into socialSecurityBenefits and box 6 into withholding, so the § 86 taxable-benefits worksheet runs on the transcribed total instead of a hand-mapped guess. The tool derives wages/withholding (incl. Form 8959 Part IV), box-3/5 wage coordination, dependent classifications, age facts, and early-distribution penalties deterministically — and errors if the same value is also passed as a hand-mapped fact.");
81
- const toCents = (v) => {
82
- const s = typeof v === "number" ? v.toFixed(2) : String(v).replace(/[$,]/g, "");
83
- const m = /^(-?)(\d+)(?:\.(\d{1,2}))?$/.exec(s);
84
- if (!m)
85
- throw new Error(`not a dollar amount: ${JSON.stringify(v)}`);
86
- const cents = BigInt(m[2]) * 100n + BigInt((m[3] ?? "0").padEnd(2, "0"));
87
- return m[1] === "-" ? -cents : cents;
88
- };
89
- const dollars = (c) => `${c / 100n}.${(c % 100n < 0n ? -(c % 100n) : c % 100n).toString().padStart(2, "0")}`;
90
- /** Age attained by the close of the tax year (IRS born-before-Jan-2 rule for 65). */
91
- function ageAtYearEnd(dobStr, taxYear) {
92
- const [y, m, d] = dobStr.split("-").map(Number);
93
- // attained age N during the tax year if birthday (y+N) falls on or before Dec 31;
94
- // the Jan-1 birthday counts as attained the day before (prior tax year)
95
- let age = taxYear - y;
96
- if (m === 1 && d === 1)
97
- return age; // Jan 1: deemed attained Dec 31 of prior year — age already counts
98
- return age;
99
- }
100
- /** Age in years (with the half-year test) on the last day of the tax year. */
101
- function ageYearsExact(dobStr, taxYear) {
102
- const [y, m, d] = dobStr.split("-").map(Number);
103
- const end = Date.UTC(taxYear, 11, 31);
104
- const birth = Date.UTC(y, m - 1, d);
105
- return (end - birth) / (365.25 * 24 * 3600 * 1000);
106
- }
107
- export function compileDocuments(docs, asOf) {
108
- const taxYear = Number(asOf.slice(0, 4));
109
- const sums = {};
110
- const ints = {};
111
- const bools = {};
112
- const notes = [];
113
- const add = (id, c) => {
114
- sums[id] = (sums[id] ?? 0n) + c;
115
- };
116
- // --- taxpayer / spouse ages -----------------------------------------------
117
- const born65Cutoff = (dobStr) => ageAtYearEnd(dobStr, taxYear) >= 65;
118
- if (docs.taxpayerDateOfBirth) {
119
- const age = ageAtYearEnd(docs.taxpayerDateOfBirth, taxYear);
120
- bools.isAge65OrOlder = born65Cutoff(docs.taxpayerDateOfBirth);
121
- bools.isAtLeastAge25 = age >= 25;
122
- bools.isAge50OrOlder = age >= 50;
123
- bools.isAge55OrOlder = age >= 55;
124
- notes.push(`taxpayer age at year end: ${age} (from ${docs.taxpayerDateOfBirth})`);
125
- }
126
- if (docs.spouseDateOfBirth) {
127
- bools.spouseIsAge65OrOlder = born65Cutoff(docs.spouseDateOfBirth);
128
- notes.push(`spouse age at year end: ${ageAtYearEnd(docs.spouseDateOfBirth, taxYear)} (from ${docs.spouseDateOfBirth})`);
129
- }
130
- // --- W-2s -------------------------------------------------------------------
131
- const multiW2 = (docs.w2s ?? []).length > 1;
132
- if (multiW2 && (docs.w2s ?? []).some((w) => w.box3 !== undefined)) {
133
- notes.push("MULTIPLE W-2s: box-3 sums are NOT set as socialSecurityWages (Schedule SE coordination is PER PERSON — if there is self-employment income, set income.socialSecurityWages to the SE-earner's OWN box 3 yourself)");
134
- }
135
- let w2Box1Cents = 0n;
136
- for (const [i, w] of (docs.w2s ?? []).entries()) {
137
- add("wages", toCents(w.box1));
138
- w2Box1Cents += toCents(w.box1);
139
- if (w.box2 !== undefined)
140
- add("federalTaxWithheld", toCents(w.box2));
141
- if (w.box3 !== undefined && !multiW2)
142
- add("socialSecurityWages", toCents(w.box3));
143
- if (w.box5 !== undefined) {
144
- const b5 = toCents(w.box5);
145
- add("medicareWages", b5);
146
- if (w.box6 !== undefined && b5 > 20000000n) {
147
- // Form 8959 Part IV: withholding over 1.45% of box 5 is
148
- // Additional-Medicare-Tax withholding → credited on line 25.
149
- // Only engaged above the $200,000 employer-withholding trigger
150
- // (§ 3102(f)) — below it, tiny box-6 excesses are rounding noise
151
- const regular = (b5 * 145n + 5000n) / 10000n; // 1.45%, half-up
152
- const excess = toCents(w.box6) - regular;
153
- if (excess > 0n) {
154
- add("federalTaxWithheld", excess);
155
- notes.push(`W-2 #${i + 1}: Form 8959 Part IV — box 6 exceeds 1.45% of box 5 by $${dollars(excess)}; added to withholding`);
156
- }
157
- }
158
- }
159
- if (w.box17 !== undefined && toCents(w.box17) > 0n) {
160
- notes.push(`W-2 #${i + 1}: box 17 state income tax $${dollars(toCents(w.box17))} is DOCUMENTED — include in itemized.stateAndLocalTaxesPaid if itemizing; do not discard it as anomalous`);
161
- }
162
- }
163
- // --- 1099-Rs ----------------------------------------------------------------
164
- const PENALTY_EXEMPT_CODES = new Set(["2", "3", "4", "7", "G", "H", "Q", "T", "C"]);
165
- for (const [i, r] of (docs.f1099rs ?? []).entries()) {
166
- if (r.box4 !== undefined)
167
- add("federalTaxWithheld", toCents(r.box4));
168
- const taxable = toCents(r.box2a);
169
- if (r.rolledOver || r.box7.toUpperCase().includes("G")) {
170
- notes.push(`1099-R #${i + 1}: treated as ROLLOVER (${r.rolledOver ? "interview-confirmed" : "code G"}) — gross on 4a/5a only, $0 taxable`);
171
- continue;
172
- }
173
- if (r.disabilityBeforeRetirementAge) {
174
- add("wages", taxable);
175
- add("scheduleRDisabilityIncome", taxable);
176
- notes.push(`1099-R #${i + 1}: code-3 disability before minimum retirement age — $${dollars(taxable)} reported as WAGES (Pub. 525, Form 1040 line 1h — NOT line 1a, which is W-2 box 1 only) and counted as § 22 disability income`);
177
- continue;
178
- }
179
- if (r.iraSepSimple)
180
- add("taxableIraDistributions", taxable);
181
- else
182
- add("taxablePensionsAndAnnuities", taxable);
183
- // § 72(t): the penalty is an AGE question, not a box-code question
184
- const dobStr = r.recipient === "spouse" ? docs.spouseDateOfBirth : docs.taxpayerDateOfBirth;
185
- const code = r.box7.toUpperCase();
186
- if ([...code].some((c) => c === "1")) {
187
- if (dobStr && ageYearsExact(dobStr, taxYear) >= 59.5) {
188
- notes.push(`1099-R #${i + 1}: payer code 1 (early) but the ${r.recipient ?? "taxpayer"} is over 59½ — no § 72(t) penalty (age controls, not the box code)`);
189
- }
190
- else if ([...code].every((c) => !PENALTY_EXEMPT_CODES.has(c))) {
191
- add("earlyDistributionSubjectToPenalty", taxable);
192
- notes.push(`1099-R #${i + 1}: code 1 and no age exception established — $${dollars(taxable)} subject to the 10% § 72(t) tax`);
193
- }
194
- }
195
- }
196
- // --- SSA-1099s ----------------------------------------------------------------
197
- for (const s of docs.ssa1099s ?? []) {
198
- add("socialSecurityBenefits", toCents(s.box5));
199
- if (s.box6 !== undefined)
200
- add("federalTaxWithheld", toCents(s.box6));
201
- }
202
- // --- dependents: statute tests, not checkbox labels --------------------------
203
- for (const dep of docs.dependents ?? []) {
204
- const age = ageAtYearEnd(dep.dateOfBirth, taxYear);
205
- const disabled = dep.isPermanentlyDisabled === true;
206
- const student = dep.isFullTimeStudent === true;
207
- const ssn = dep.hasRequiredSSN !== false;
208
- const months = dep.monthsLivedWithTaxpayer ?? 12;
209
- // § 152(c)(2): only child/descendant or sibling/descendant lineage can be
210
- // a qualifying child — a PARENT can never be one (EIC-child included)
211
- const childLineage = (dep.relationship ?? "child_or_descendant") !== "parent_or_other_relative";
212
- if (months <= 6 && !disabled) {
213
- notes.push(`dependent (b. ${dep.dateOfBirth}): lived ≤6 months — residency test not met, excluded (divorced-parents release etc. via determine_dependent)`);
214
- continue;
215
- }
216
- if (!childLineage) {
217
- ints.otherDependents = (ints.otherDependents ?? 0) + 1;
218
- if (disabled)
219
- ints.careQualifyingIndividuals = (ints.careQualifyingIndividuals ?? 0) + 1;
220
- notes.push(`dependent (b. ${dep.dateOfBirth}, parent/other relative): qualifying RELATIVE — $500 ODC only, never a CTC/EIC qualifying child (§ 152(c)(2))${disabled ? "; CDCC-qualifying (incapable of self-care)" : ""}`);
221
- continue;
222
- }
223
- if (age < 17 && ssn) {
224
- ints.qualifyingChildren = (ints.qualifyingChildren ?? 0) + 1;
225
- notes.push(`dependent (b. ${dep.dateOfBirth}, age ${age}): CTC qualifying child — § 24(c) age test controls regardless of any intake 'other dependent' checkbox`);
226
- }
227
- else {
228
- ints.otherDependents = (ints.otherDependents ?? 0) + 1;
229
- // EIC qualifying child has WIDER age rules than the CTC
230
- if (age < 19 || (age < 24 && student) || disabled) {
231
- ints.eitcAdditionalQualifyingChildren = (ints.eitcAdditionalQualifyingChildren ?? 0) + 1;
232
- notes.push(`dependent (b. ${dep.dateOfBirth}, age ${age}): $500 ODC for the CTC, but an EIC qualifying child (§ 32(c)(3): ${disabled ? "disabled, any age" : student ? "student under 24" : "under 19"})`);
233
- }
234
- }
235
- if (age < 13 || disabled) {
236
- ints.careQualifyingIndividuals = (ints.careQualifyingIndividuals ?? 0) + 1;
237
- }
238
- }
239
- const facts = { ...bools };
240
- for (const [id, c] of Object.entries(sums))
241
- facts[id] = dollars(c);
242
- for (const [id, n] of Object.entries(ints))
243
- facts[id] = n;
244
- return { facts, notes, w2Box1Cents };
245
- }
246
- //# sourceMappingURL=documents.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"documents.js","sourceRoot":"","sources":["../src/documents.ts"],"names":[],"mappings":"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"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Entry for the self-contained hosted bundle (site /mcp route, edge-less
3
- * Node runtimes). Exports the server factory plus the SDK's Web-Standard
4
- * Streamable HTTP transport so the host app needs zero MCP dependencies.
5
- */
6
- export { createServer } from "./server.js";
7
- export { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
8
- //# sourceMappingURL=hosted-bundle.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hosted-bundle.d.ts","sourceRoot":"","sources":["../src/hosted-bundle.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,wCAAwC,EAAE,MAAM,+DAA+D,CAAC"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Entry for the self-contained hosted bundle (site /mcp route, edge-less
3
- * Node runtimes). Exports the server factory plus the SDK's Web-Standard
4
- * Streamable HTTP transport so the host app needs zero MCP dependencies.
5
- */
6
- export { createServer } from "./server.js";
7
- export { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
8
- //# sourceMappingURL=hosted-bundle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hosted-bundle.js","sourceRoot":"","sources":["../src/hosted-bundle.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,wCAAwC,EAAE,MAAM,+DAA+D,CAAC"}
package/dist/http.d.ts DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * @invaro/opentax Streamable HTTP entry — the same tax oracle as a remote MCP
4
- * connector URL (spec 2025-03-26 Streamable HTTP transport, stateless mode).
5
- *
6
- * Run: opentax-mcp-http (PORT env, default 3411)
7
- * Then: add https://<host>/mcp as a custom connector (Claude.ai, ChatGPT,
8
- * Cursor, `claude mcp add --transport http opentax <url>`).
9
- *
10
- * Stateless by design: every POST gets a fresh server + transport, so the
11
- * process scales horizontally with no session affinity. The corpus is loaded
12
- * once per process and shared (it is immutable and content-addressed).
13
- */
14
- export {};
15
- //# sourceMappingURL=http.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG"}
package/dist/http.js DELETED
@@ -1,90 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * @invaro/opentax Streamable HTTP entry — the same tax oracle as a remote MCP
4
- * connector URL (spec 2025-03-26 Streamable HTTP transport, stateless mode).
5
- *
6
- * Run: opentax-mcp-http (PORT env, default 3411)
7
- * Then: add https://<host>/mcp as a custom connector (Claude.ai, ChatGPT,
8
- * Cursor, `claude mcp add --transport http opentax <url>`).
9
- *
10
- * Stateless by design: every POST gets a fresh server + transport, so the
11
- * process scales horizontally with no session affinity. The corpus is loaded
12
- * once per process and shared (it is immutable and content-addressed).
13
- */
14
- import { createServer as createHttpServer } from "node:http";
15
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
16
- import { createServer } from "./server.js";
17
- const PORT = Number(process.env.PORT ?? 3411);
18
- const PATH = process.env.MCP_PATH ?? "/mcp";
19
- function readBody(req) {
20
- return new Promise((resolve, reject) => {
21
- let raw = "";
22
- req.on("data", (c) => (raw += c));
23
- req.on("end", () => {
24
- if (!raw)
25
- return resolve(undefined);
26
- try {
27
- resolve(JSON.parse(raw));
28
- }
29
- catch (err) {
30
- reject(err);
31
- }
32
- });
33
- req.on("error", reject);
34
- });
35
- }
36
- function cors(res) {
37
- res.setHeader("Access-Control-Allow-Origin", "*");
38
- res.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS");
39
- res.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, Mcp-Session-Id, MCP-Protocol-Version, Last-Event-ID");
40
- res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
41
- }
42
- const httpServer = createHttpServer(async (req, res) => {
43
- cors(res);
44
- const url = (req.url ?? "/").split("?")[0];
45
- if (req.method === "OPTIONS") {
46
- res.writeHead(204).end();
47
- return;
48
- }
49
- if (url === "/healthz") {
50
- res.writeHead(200, { "Content-Type": "application/json" }).end('{"ok":true}');
51
- return;
52
- }
53
- if (url !== PATH) {
54
- res.writeHead(404, { "Content-Type": "application/json" }).end('{"error":"not found — the MCP endpoint is ' + PATH + '"}');
55
- return;
56
- }
57
- if (req.method !== "POST") {
58
- // stateless mode: no SSE resumption stream, no sessions to DELETE
59
- res.writeHead(405, { Allow: "POST, OPTIONS" }).end();
60
- return;
61
- }
62
- try {
63
- const body = await readBody(req);
64
- const server = createServer();
65
- const transport = new StreamableHTTPServerTransport({
66
- sessionIdGenerator: undefined, // stateless
67
- enableJsonResponse: true,
68
- });
69
- res.on("close", () => {
70
- void transport.close();
71
- void server.close();
72
- });
73
- await server.connect(transport);
74
- await transport.handleRequest(req, res, body);
75
- }
76
- catch (err) {
77
- if (!res.headersSent) {
78
- res.writeHead(400, { "Content-Type": "application/json" });
79
- }
80
- res.end(JSON.stringify({
81
- jsonrpc: "2.0",
82
- error: { code: -32700, message: String(err?.message ?? err) },
83
- id: null,
84
- }));
85
- }
86
- });
87
- httpServer.listen(PORT, () => {
88
- console.error(`opentax MCP (Streamable HTTP, stateless) listening on :${PORT}${PATH}`);
89
- });
90
- //# sourceMappingURL=http.js.map
package/dist/http.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}