Back to Browse

Taxtrace MCP Server

Developer ToolsLow Risk10.0MCP RegistryLocal
Free

Server data from the Official MCP Registry

Masked, read-only views of a local tax workspace: documents, form checks and to-dos.

About

Masked, read-only views of a local tax workspace: documents, form checks and to-dos.

Security Report

10.0
Low Risk10.0Low Risk

Valid MCP server (1 strong, 2 medium validity signals). No known CVEs in dependencies. Package registry verified. Imported from the Official MCP Registry.

4 files analyzed · 1 issue found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

file_system

Check that this permission is expected for this type of plugin.

Shell Command Execution

Runs commands on your machine. Be cautious — only use if you trust this plugin.

What You'll Need

Set these up before or after installing:

Path to your tax workspace folder (documents by tax year, todo.md). Defaults to ~/TaxData. Outside any git repository.Optional

Environment variable: TAXTRACE_HOME

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-vinayvobbili-taxtrace": {
      "env": {
        "TAXTRACE_HOME": "your-taxtrace-home-here"
      },
      "args": [
        "taxtrace"
      ],
      "command": "uvx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

taxtrace

Prepare a US federal and state return from your own documents, on your own machine, with every number traced to the page it came from.

taxtrace does not file anything. It reads a folder of your documents (W-2s, 1099s, 1098s, property manager statements, receipts, foreign bank statements, last year's return) and produces an entry sheet you type into consumer tax software, an FBAR account list, and a list of questions for you: anything it couldn't settle from the documents alone.

Three rules hold everywhere:

  1. Nothing is guessed. Every value carries the file, the page and the exact text it was read from, and a deterministic check rejects any value whose quote isn't on that page.
  2. Your documents never leave your machine. Where a language model reads them (sorting documents, reading messy receipts), it is a local MLX model on your Mac. The chat can use a cloud model, which only ever sees masked text (see Chat).
  3. Nothing is decided silently. A receipt that could be a repair or an improvement, a missing 1099, a rate choice: each is a question for you, with the evidence next to it.

Status

Early. What works today:

  • taxtrace redact: masks a document down to its layout, so a layout can be studied (by a person or an AI assistant helping write a parser) without its values, names or places. Every digit becomes #, and every word the IRS's own publications don't use in lowercase becomes *s, so names, streets and towns go without anyone listing them.

  • taxtrace import, outline and unlock: sort a preparer's export into the workspace, list the forms in each document, and check passwords kept in the Keychain.

  • taxtrace prior: reads a filed return's carryforwards (see Carryforwards).

  • taxtrace k1: reads each Schedule K-1 (Form 1065) face, every box and code, its statements, the Schedule K-3, and North Carolina's D-403 NC K-1 (see K-1s).

  • taxtrace passive: each passive activity's year and the loss it carries in (see Passive activities).

  • taxtrace 1098: reads each Form 1098 mortgage interest statement (see Form 1098).

  • taxtrace 1099: reads the 1099-DIVs, 1099-INTs and 1099-Bs on brokers' consolidated 1099 statements (see Forms 1099-DIV and 1099-INT and Stock sales).

  • taxtrace rental: puts the rental's Schedule E together, line by line (see Schedule E).

  • taxtrace qbi: Form 8995, the qualified business income deduction (see Form 8995).

  • taxtrace paystub: reads a pay stub's income tax withheld, and projects the year's (see Estimated tax).

  • taxtrace estimates: the year's withholding and estimated payments against the safe harbor, quarter by quarter (see Estimated tax).

  • taxtrace ira: each spouse's IRA deduction and the Roth IRA's limit at the year's projected income (see IRAs).

  • taxtrace jobchange: the year as the pay stub projects it, against leaving one job and starting another (see A change of job).

  • taxtrace sales: the year's stock sales for Schedule D, the wash-sale windows, and the room left for losses (see Stock sales).

  • taxtrace moves: the year's tax-saving moves, ranked by the dollars each saves, with deadlines (see The year's moves).

  • taxtrace itr: reads India's income tax return (ITR-2): a property sale, the interest, the tax India kept (see India's return).

  • taxtrace bank: reads a foreign bank's statement of account: interest, a tax refund, balances (see Bank statements).

  • taxtrace entry: the year's entry sheet, to type into a filing site (see Entry sheet).

  • taxtrace ui: the workspace in the browser, with a chat (see Chat).

  • taxtrace agi: the year's federal adjusted gross income, against the filed return when there is one (see Adjusted gross income).

  • taxtrace d400: North Carolina's Form D-400 with Schedules S and A (see Form D-400).

  • taxtrace w2: reads Form W-2s into the entry sheet, agi and d400 (see Form W-2).

  • taxtrace tax: Form 1040's lines 12e to 24 with Form 1116's credit (see Total tax).

  • taxtrace yoy: a year against the one before (see Year over year).

Install

pip install -e ".[dev,mcp]"

taxtrace[chat] adds the chat's Claude SDK and taxtrace[mcp] an MCP server. The chat's model on your own computer is whatever OpenAI-compatible server answers at http://127.0.0.1:8010/v1 (vllm-mlx serve <model> --port 8010, mlx_lm.server, LM Studio; LOCAL_LLM_URL points elsewhere on the same computer). taxtrace never loads a model itself, so one server can hold a single copy for every program, and it refuses a server on another machine, since that model sees your values unmasked.

Use

taxtrace import ~/Downloads/portal-export.zip  # filed returns to prior-returns/, the rest by tax year
taxtrace redact ~/TaxData/prior-returns        # writes ~/TaxData/redacted/*.txt

A path that isn't one from where you are is looked up in the workspace: taxtrace k1 2025 reads <workspace>/2025.

taxtrace outline <files> lists each page's masked heading: which forms a document holds, in order (--match '1116|4562' lists only the pages naming them). taxtrace words <pdf> --page 2 --rows shows a page's words, masked, with where each one sits (--x 300:450 and --top 70:240 narrow it to a region): the geometry of a printed form, for writing a reader of it. --marks adds the drawn shapes, so a checkbox ticked with a drawn mark shows. --page 19-20,69, --page all and several files take one run, so files that share a Keychain entry cost one approval. taxtrace show 'prior-returns/2025*' --page 19 opens a document in Chrome at a page, for you to read yourself. A scanned PDF (pictures of pages, no text) is read through ocrmypdf on your machine (brew install ocrmypdf), once: the searchable copy is kept under the original's sha256 in <workspace>/ocr-cache, so the text values are quoted from never shifts. A picture (.jpg, .png: a phone's photo or screenshot of a statement, as one arrives in a chat) goes the same way. A chat app shrinks what it sends, though, and a blurred table's rows may not read: bank then saves nothing for that account, and a PDF from the bank (or the picture sent as a document, uncompressed) is the better copy.

import takes a folder or a zip, such as a tax preparer's portal export with one folder per year. It skips identity documents (driver's licenses, Social Security cards, passports) and anything already imported, and records every file it places, with its sha256, in imports.jsonl.

Your documents and everything derived from them live in a workspace folder, ~/TaxData or $TAXTRACE_HOME, which taxtrace refuses to place inside a git repository. Names that are also ordinary words (Will, Grace) go in <workspace>/redact-terms.txt, one per line.

A password-protected PDF is read with a password kept in the macOS Keychain, never in a file or on a command line. One default entry covers every return that shares a password; an entry under a file's name wins for that file, and one under the name before its first - covers a bank's monthly statements (quillbank for quillbank-4410-2026-01.pdf, quillbank-4410-2026-02.pdf, ...). security asks for it without echoing, and -T "" trusts no app, so macOS asks you (Allow / Deny) each time anything reads it, taxtrace included:

security add-generic-password -s taxtrace -a default -T "" -w
security add-generic-password -s taxtrace -a "2024 Return.pdf" -T "" -w   # just this file
security add-generic-password -s taxtrace -a quillbank -T "" -w           # quillbank-*.pdf

Click Allow, not Always Allow: that would add the reader to the trusted list and end the prompts.

That prompt only takes the typed password. To approve each read with Apple Watch or Touch ID instead:

taxtrace keychain setup                              # the default entry and the chat's key
taxtrace keychain setup --account "2024 Return.pdf"  # and a file's own entry

setup builds a small helper (taxtrace/macos/keychain_gate.swift, compiled with the Xcode command line tools) and moves each entry over to it. macOS asks for the entry the old way one last time, and the secret is never retyped or shown. From then on the entry trusts only the helper, and the helper releases it only after macOS's own approval: Apple Watch, Touch ID, or the password where neither is set up. Every read is still yours to allow. Only the entries setup moved go through the helper; any other is read the classic way, with its one prompt. If you deny the classic prompt during setup, it says so and leaves that entry as it was: run setup again. Once the helper is built, store a new password with taxtrace keychain store <name> (a file's name, its issuer's such as quillbank, or default): security asks for it unechoed, then the helper moves it over the way setup does, with one classic prompt. An entry stored with a bare security add-generic-password -T <helper> stays security's: macOS adds its own prompt to every read the helper makes, on top of Apple Watch or Touch ID. taxtrace reads each entry at most once per command, so a folder of returns sharing the default password costs one prompt. taxtrace unlock says which entry opens each locked file, and how each stored password is shaped (aaaa99999), never what it is. A password pdfminer turns down is tried once more with qpdf (brew install qpdf), which gets it on stdin and decrypts a copy into a temporary folder for the read: when qpdf turns it down too, the stored password is wrong, not the reader.

Another tool can read an entry setup moved, such as an API key it shares with the chat, without the entry trusting that tool too:

taxtrace keychain read anthropic --for jobwatch   # the secret on stdout, once approved

The prompt names the item and the tool. The secret goes to the program that runs the command, never to a terminal, and an entry setup didn't move isn't read this way.

A tool that reads the key unattended (a background service after a restart) has nobody there to approve, and the approval times out. For a key that guards little, such as one with a spend limit, taxtrace keychain release anthropic moves it back for good: one approval, then security saves it again (the secret on its stdin, never in a command line) and it reads without any prompt, taxtrace's chat included. The document passwords can't be released.

When a read asks for the password instead of Apple Watch or Touch ID (a Watch out of range, asleep or locked falls back to it), taxtrace keychain check says which ways macOS offers right now and why not, and check --try shows one Watch / Touch ID prompt and prints what came back. Neither rebuilds the helper or touches an entry.

Besides PDFs and text files (.txt, .csv), Word documents (.docx: one line per paragraph and per table row) and Excel workbooks (.xlsx: a page per sheet, one line per row) are read, with Python's own zip and XML modules. A password-protected Office file isn't read: save an unprotected copy into the workspace.

redact, outline and unlock with no paths read the whole workspace, leaving out what taxtrace wrote there itself (redacted/, ocr-cache/).

Carryforwards

taxtrace prior            # every return in <workspace>/prior-returns
taxtrace prior --layout   # also each line a value came from, masked
taxtrace prior --words 23-26,71   # also those pages' masked words, in the same run (one Keychain approval)

Next year's return starts from last year's: each asset's depreciation so far, and each passive activity's loss that couldn't be taken yet. prior reads them from the preparer's own printouts: the federal depreciation schedule (Drake's "Federal Depreciation Schedule", or its "Depreciation Detail Listing", whose land rows carry forward as cost with no depreciation) and Form 8582's Worksheets 5 and 6. Where the return prints "Next Year's Depreciation Worksheet", each asset's deduction there is checked against a year rolled forward. The values go to <workspace>/carryforwards/<return>.json, each with its page and the exact line it was read from. The terminal gets counts, failed checks and questions, masked like redact's output.

Nothing is taken on trust:

  • Every row is added up against the schedule's totals line, and each asset's depreciation so far against its basis.
  • On Form 8582, each activity's ratio is checked against its share of the loss, its unallowed loss against its ratio of the total, and Worksheet 6 against Worksheet 5.
  • Worksheets 1 and 3 list every passive activity, with income as well as loss: its net income, net loss, the unallowed loss it brought in, and the overall gain or loss. A row leaves the columns it doesn't use empty, so each amount is read by where it sits, under its column's heading. Each row has to come to its overall gain or loss, and the rows to the total line.
  • A schedule printed twice is kept once, and a second copy that disagrees is a question.
  • The alternative minimum tax and book copies are skipped. So is next year's projected schedule, which is checked to start from this year's accumulated depreciation.
  • A Section 179, bonus or salvage amount, or business use under 100%, is a question for you, not a guess.
  • Schedule B (Form 1116) gives the foreign tax carried to next year, per category of income (passive, general...) and again for the alternative minimum tax, by the year each tax arose: its columns are the ten years before this one, this year and a total. Each column's lines have to combine (line 3 is lines 1 and 2, line 8 is lines 3 through 7), the subtotal has to carry from page 1 to page 2, and the total has to add up its columns. The AMT copy's page 2 doesn't say it's the AMT copy, so it goes with the nearest page 1. A box left unchecked is a question. The terminal shows only the years a carryover arose in.
  • The Carryover Worksheet (Drake's "List of items that will carryover to the next tax return") is read row by row: state and local taxes paid, the QBI loss, the foreign tax credit (regular and AMT), last year's tax for the estimated-tax safe harbor, each spouse's IRA basis. Its foreign tax credit has to equal Schedule B's carryover, and its heading has to name the next year. Anything under Passive Activity or At Risk Limitations is a question, since no copy seen so far had rows there. --layout lists each row's label and which amounts it has (regular, AMT, taxpayer, spouse), never the amounts.
  • Form 8995 (the simplified QBI deduction) gives each business's qualified business income (line 1, continued on its own page past five businesses) and lines 2 to 17. Its arithmetic is checked line by line, its QBI and REIT/PTP losses carried on (lines 16 and 17) have to be the Carryover Worksheet's and the next year's lines 3 and 7.
  • Form 1040 gives the lines next year's estimated tax goes by: the adjusted gross income, the total tax, the withholding, the estimated payments, the refundable credits, the total payments, the overpayment, what of it went to next year, and the estimated tax penalty. Each is found by its number and words of its label, and the payments have to add up.
  • Returns years apart are checked against each other. An asset's depreciation is rolled forward a full year at a time, and has to match the later return's prior depreciation. A miss says how far off it is in years of depreciation (0.46 years is a first, partial year left out), with no amounts. A year's foreign tax carried to the following year has to be the next year's carryover from the prior year, year by year.
taxtrace prior --project 2025   # roll the latest schedule forward, for returns not in hand yet

--project writes <workspace>/carryforwards/projected-<year>.json: each asset's depreciation for every year since the latest return, marked as projected until that year's return arrives to confirm it. --layout also shows each asset's prior and current depreciation in years. That's enough to spot a missing or partial year without seeing an amount.

K-1s

taxtrace k1 2025            # every K-1 face in <workspace>/2025
taxtrace k1 2025 --layout   # also each value's text, masked, and where it sits

A K-1's face is a printed form: each amount sits in its box under the box's number, with its code beside it, so read in order an amount lands next to whatever label is beside it on the page. k1 reads by position instead. It finds Part III's two columns by their first boxes and gives each amount to the nearest box number above it in its column. Parts I and II are read by their labels: the EIN, the partnership, the partner (last four digits of the TIN), each check mark, profit, loss and capital shares, liabilities, and the capital account. The values go to <workspace>/k1/<document>.json, each with its page, position and exact text. The terminal gets the boxes and codes that hold amounts, with failed checks and questions, never an amount or a name.

  • Item L's capital account has to add up: beginning, plus contributions, this year's income and other changes, less withdrawals, is the ending balance. Each share has to be between 0% and 100%, and each amount in a box with codes has to have one.
  • A face printed twice for the same partner counts once. The same amounts for another partner, such as a spouse, are that partner's own K-1.
  • An IRA's K-1 (item I2 checked) is marked as one: its income stays in the account, off the return.
  • An amount the face sends to the partnership's statement ("STMT", "See statement") is read from the statement pages after the face. A "Line 20, Code Z" or "Box 19C" reference, or a code in a box's table, ties each amount line under it to its box and code, with its description; a label wrapped around its amount (Statement A's 199A grid) is put back together. Totals and item L's reconciliation, which repeat amounts given elsewhere, are left out. A statement amount the pages don't give is a question.
  • Each Section 199A amount is marked with its kind (qualified business income, W-2 wages, UBIA, REIT dividends, PTP income) and the trade or business it's for. An aggregated group's totals are kept but marked as the group's, so they're never added in a second time, and each one has to be its businesses' amounts added up.
  • A final K-1, or more than one activity (boxes 22, 23), is a question.

North Carolina's partner K-1 (Form D-403 NC K-1) is read the same way, by where things sit. Each of its eleven lines has its amount just above the line's label, and the partnership's FEIN, the partner's number (only its last four digits are kept) and the three Yes/No answers are read by their labels. It goes to the same folder, with where the D-400 takes each line.

  • Line 1 has to be the same partnership's federal K-1, Part III lines 1 to 11 added up, as the form says. The federal K-1 can be read in the same run or an earlier one; if none has been read, that's a question.
  • Lines 6 to 9 are for nonresident partners and 10 and 11 for taxed partnerships: an amount there on a K-1 whose answers say it isn't one fails.
  • Additions and deductions (lines 2, 3) and credits (line 4) are a question: the form doesn't say which Schedule S or D-400TC line each belongs on.

A Schedule K-3 (the partner's international items) is read for Form 1116: box E's marks for which parts apply, and every amount in Part II (gross income and deductions by source and category), each with its line, its country row and country code, and its column, from (a) U.S. source through the foreign categories to the total. Part III's foreign taxes are noted.

  • Each row's columns have to add up to its total, and each total line to the lines its label names ("combine lines 1 through 23", "subtract line 54 from line 24").
  • Part II's interest, dividends, gains and section 1231 lines have to match the same partnership's K-1 boxes, and a K-1 whose box 16 says a K-3 is attached has to have one read, now or on an earlier run.
  • The terminal says whether any of Part II is foreign source and in which categories. Foreign taxes are a question for now: their table isn't read yet.

Passive activities

taxtrace passive            # the latest year of the K-1s read
taxtrace passive --year 2025

Form 8582 limits passive losses, and what it doesn't allow carries to the next year activity by activity. passive starts from the latest return's worksheets as prior saved them (every activity on Worksheets 1 and 3, and what each carries on from Worksheet 5) and goes on with this year's K-1s as k1 saved them. It opens no document. Each activity is matched to its partnership's K-1 by the words of its name, and its year is the K-1's boxes 1, 2, 3 and 10, less box 12. Interest, dividends and portfolio deductions aren't the activity's. A K-1 no activity matches is a new activity. The ledger goes to <workspace>/passive/<year>.json; the terminal gets each activity's masked name, where its year comes from and whether it's income or a loss, never an amount.

  • An activity with no K-1 this year is a question: sold, ended, or missing from the folder? A full disposition (a final K-1) frees the loss it carries.
  • What each activity carries in comes from last year's Worksheet 5. When last year's copy has none, its Carryover Worksheet's Passive Activity section printed empty means nothing carries in; failing that, last year's ledger (activities sold last year dropped) and the Form 8582 passive worked out for it. Each is a note to confirm against the filed Worksheet 5, and with none of them what each carries in is left unknown.
  • A return whose Worksheet 5 carries losses on, followed by a return whose Carryover Worksheet lists none, is a question: the next year's passive income allowed them all, or they were left off and lost to every later year.
  • The rental's year comes from Schedule E (rental), and a box 13 deduction whose code doesn't settle whether it's the activity's is a question.

With every activity's year and carried loss known, passive works the year's Form 8582 out and saves it with the ledger:

  • Each activity goes in Part IV (rental real estate with active participation: the latest return's Worksheet 1) or Part V (every other one, a partnership's new activity too). Line 3 adds them up; zero or more, and every loss is allowed.
  • Part II's special allowance (up to $25,000, phased out between $100,000 and $150,000 of modified adjusted gross income) needs --confirm magi=AMOUNT; married filing separately also needs lived_apart=yes|no. It goes to the Part IV activities first (Part VI).
  • The rest of line 3's loss is unallowed, shared by the activities with an overall loss in proportion to their losses (Part VII), and carries to next year. An activity disposed of in full at an overall loss is off the form: its losses, carried ones too, are allowed in full.
  • Every filed return whose worksheets were read is worked out again from its own Worksheets 1 and 3 and checked against its Worksheet 5: the same arithmetic, rehearsed on the preparer's numbers.

The terminal says what each activity's loss does (allowed, part carried on, off the form), never how much.

Form W-2

taxtrace w2 "2026 W-2 Initech.pdf" writes forms/2026 W-2 Initech.json: boxes 1 to 8, 10, 11, 12 (each code with its amount), 16 to 19, the state in box 15, the employer's name and EIN, and the year.

The IRS's form and a payroll company's substitute hold the same boxes in different places, so each box is found by the words of its label, and its value under or beside that label. Two or four copies on a page, or the same form on another page, count once. If the copies show different wages, it asks, since that may be a second employer's.

Only the last four digits of the employee's Social Security number are kept. Box 13's checkboxes and box 14 aren't read: the entry sheet says to type box 13 from the form.

It checks that box 4 is 6.2% of box 3 and box 6 at least 1.45% of box 5, and asks about what needs another form: box 8 (allocated tips), box 10 (Form 2441), box 11, code W in box 12 (Form 8889), a second state's row, and a corrected W-2c.

The entry sheet shows the W-2's boxes in place of the pay stub's estimate, agi uses box 1 for wages, and d400 uses box 17 for the state tax withheld. Box 10's dependent care benefits follow Form 2441: what's excluded is the smallest of the benefits, the care expenses, each spouse's earned income and the year's limit, and the rest is wages on line 1e, so a joint return with no earned income for the spouse excludes nothing (agi --confirm care_expenses= spouse_earned=). The tests read the words of the IRS's own page with made-up values printed on it (scripts/make-w2-fixture).

Form 1098

taxtrace 1098 2025            # every Form 1098 in <workspace>/2025
taxtrace 1098 2025 --layout   # also each value's text, masked, and where it sits

A lender's 1098 is a printed form too. Each box is found by its number and the first words of its label, matched with the spaces taken out, since a lender's print can split a word ("M ortgage"). Its value is what sits under the label, from the box's number to the next box's label beside it or below it. The lender's TIN, the borrower's (last four digits only), the account number and the calendar year are read by their labels. The values go to <workspace>/forms/<document>.json; the terminal gets which boxes hold amounts, the checks and the questions.

  • Box 1 has to be there, and has to be under 15% of box 2's principal: more is a misread, not a mortgage.
  • Box 10 (other) isn't interest. What the lender prints beside it (often taxes or insurance paid from escrow) decides where it goes, so it's a question, as are a refund of interest (box 4), insurance premiums (box 5), points (box 6), more than one property (box 9) and a corrected form.
  • Box 8's address, or box 7's mark, says which property the interest is for: a rental's goes on Schedule E line 12, a home's on Schedule A. A 1098 with neither is a question.

Forms 1099-DIV and 1099-INT

taxtrace 1099 2025            # every consolidated 1099 statement in <workspace>/2025
taxtrace 1099 2025 --layout   # also the account and each box's label, with its value masked
taxtrace 1099 2025 --unlock   # also ask the Keychain for locked documents' passwords

Brokers' statements are seldom locked, so a locked document is skipped without asking the Keychain unless --unlock is given: the folder's other locked files (a W-2, a return) never prompt.

A broker's consolidated statement prints each form as a column of rows under its title ("1099-DIV Dividends and Distributions - 2025 ..."), the forms side by side: a box's id, its label, and the amount well right of the label. A box id printed a little under its label's line is on that row. The year is the title's; the payer's TIN and the account number are read by their labels. A statement printed twice counts once. The values go to <workspace>/forms/<document>.json; the terminal gets which boxes hold amounts, the checks and the questions.

  • The form's own arithmetic is checked: qualified dividends (1b), section 897 ordinary dividends (2e) and section 199A dividends (5) are each part of the ordinary dividends (1a), and 2b, 2c, 2d and 2f part of the capital gain distributions (2a).
  • Box 5 is Form 8995 line 6 (qbi).
  • The boxes that change where an amount goes are questions: foreign tax paid (with box 8's country), a return of capital (box 3), tax withheld, liquidation distributions, exempt-interest dividends, and on a 1099-INT the early withdrawal penalty, Treasury interest (North Carolina doesn't tax it), tax-exempt interest and bond premium. So is a corrected form.

Schedule E

taxtrace prior                 # also reads the filed returns' Schedule E: the property, lines 3 to 20, line 19's list
taxtrace 1098 2025
taxtrace rental --year 2025    # reads the answers and policies in <workspace>/2025, writes schedule-e/2025.json

rental puts one property's Part I together from what's been read, each line with where it came from:

  • Rents and expenses from the answers typed into the preparer's questions ("Rental income = $1,200/month", "Repairs = $400/year"), under a rental heading. A month's amount is taken twelve times, and that's a question.
  • Mortgage interest (line 12) from the 1098 whose box 8 is the property's address, and its box 10, when the lender's description says taxes or insurance paid from escrow, on line 16 or 9.
  • Insurance (line 9) from the landlord policy's declarations page for the property: its annual premium. A policy new this year is a question: an earlier one's premium paid this year counts too.
  • Depreciation (line 18) from the latest filed depreciation schedule prior saved, rolled forward without opening the return again (or prior --project's, when it's newer). Rolled over more than one year, it's a question.

When the year's own return has been filed and read, each line is checked against its Schedule E: a rehearsal that shows which lines the build and the preparer part on, and whether taxtrace's is more or less, never by how much.

What only you know is settled with --confirm, kept in schedule-e/<year>-confirmed.json for every later run: fair_rental_days=365, personal_use_days=0, rent_all_year=yes, rent=AMOUNT (the rent every tenant paid in the year, together, in place of the answers' monthly figure), earlier_policy=AMOUNT (a premium paid this year for a policy before the one read, 0 for none), dues=AMOUNT (association dues, line 19), and cleaning=AMOUNT and repairs=AMOUNT (the year's receipts added up, lines 7 and 14, a repair a tenant paid out of the rent among them).

A document goes with the property when its address has the same house number and street. A line the latest filed Schedule E had that this year has nothing for (association dues on line 19) is a question, as are the fair rental and personal use days. Locked documents are skipped without a Keychain prompt: answers and policies aren't locked.

Form 8995

taxtrace qbi --year 2025            # writes qbi/2025.json from what k1, rental and prior saved
taxtrace qbi --year 2025 --layout   # also each K-1's Section 199A statement rows: what each is and its sign
taxtrace qbi --year 2025 --confirm k1_4567=business --confirm rental=not

qbi puts the simplified Form 8995 together from what's been saved, opening no document:

  • Each partnership's qualified business income is its K-1's passive income or loss (boxes 1, 2, 3 and 10, less 12), the figure a preparer's Form 8995 carries, rather than the Section 199A statement's own total.
  • The rental's is Schedule E's net from rental.
  • A passive loss Form 8582 doesn't allow isn't qualified business income until a later year allows it. Each activity's amount is what the year's Form 8582 let through (its overall gain or loss, less what it carried on): the filed one when the year's return is read, otherwise the one passive worked out. With neither, the amounts are before that limit, and that's a question.
  • Which businesses count follows last year's filed Form 8995: a partnership it listed (by its EIN's last four digits) that has income or a loss this year, and the rental if it listed a Schedule E. One it didn't list is a question for --confirm k1_<last four>=business|not (or rental=), kept in qbi/<year>-confirmed.json.
  • Line 6 is the K-1s' REIT dividends and PTP income and the year's 1099-DIVs' section 199A dividends (box 5, from taxtrace 1099). Last year's losses carried on (lines 16 and 17) come in on lines 3 and 7. Lines 11 to 15 need taxable income, so the deduction is known only when line 10 is zero. The threshold for the simplified form follows the filing status foreign --confirm filing= kept; above it Form 8995-A applies, which taxtrace doesn't do yet.

When the year's own return has been filed and read, every line and business is checked against its Form 8995. A business whose amount disagrees names the other figure the filed one matches (the Section 199A statement's total, an aggregated group's, the filed Schedule E's net), so a rehearsal shows where a build and the preparer part ways. The terminal gets which businesses are income or a loss, the checks and the questions, never an amount.

Estimated tax

taxtrace prior                                   # reads last year's Form 1040 and Carryover Worksheet
taxtrace paystub 2026/payslip.pdf                # the latest pay stub: the year's withholding, projected
taxtrace estimates --year 2026 --confirm paid_2026-09-15=2500

A pay stub's header row gives the pay period and the payment date, and its taxes table each tax's amount this paycheck and the year to date ("FIT Withheld", "SIT Withheld (NC)"). The year's withholding is the year to date's plus this paycheck's for each one left: the pay period's length says how often you're paid, and each later paycheck is paid as long after its period ends as this one was, so a December period paid in January counts next year. A bonus or a new W-4 changes that, so it's a question.

taxtrace paystub --rate 47 says what each paycheck left would take home at a 47% pre-tax 401(k) deferral: this paycheck's net pay, less the deferral's change, plus the federal withholding it moves (the percentage method: the year's brackets past the standard deduction, on the paycheck's taxable wages times the paychecks in a year) and the state's at its flat rate, until the year's limit stops the deferrals. The terminal gets each paycheck's take-home as a share of this one's and the cents of take-home a deferred dollar costs; the amounts go to the file, and --show prints them in your own terminal only.

No underpayment penalty is due when the year's payments reach the smaller of 90% of the year's own tax and 100% of last year's (110% when last year's adjusted gross income was over $150,000, $75,000 married filing separately). Last year's tax is the Carryover Worksheet's federal tax liability, or Form 1040's line 24 less line 32.

A quarter of it is due by each of April 15, June 15, September 15 and January 15, and each quarter is checked on its own. An estimated payment counts on the day it's made, so a January payment can't make up an earlier quarter. Withholding counts as paid evenly through the year, however late, so more withholding before December 31 makes up every quarter, and estimates says how much would. Last year's overpayment applied to this year counts in April.

What only you know is kept in estimates/<year>-confirmed.json: withheld=AMOUNT (the year's federal tax withheld in all, in place of the pay stub's projection, when there's more than one job or a 1099 withholds too), paid_YYYY-MM-DD=AMOUNT (each estimated payment) and tax=AMOUNT (the year's own tax, once it's worked out). The terminal says which quarters are met or short; the amounts are in estimates/<year>.json.

IRAs

taxtrace ira --year 2026                       # from the latest pay stub and last year's Form 1040
taxtrace ira --year 2026 --confirm other=9000  # the year's income besides the wages, once it's known

A married couple filing jointly can each put the year's limit into an IRA, a spouse without pay on the other's pay. How much of it is deductible phases out with income: over a lower range for a spouse covered by a 401(k), a higher one for a spouse who isn't but is married to one who is. A Roth IRA has its own range. ira projects the year's income from the pay stub's federal taxable wages to December 31, as they are and with the 401(k)'s room filled (which lowers it), plus last year's interest, dividends and Schedule 1 income, and gives each spouse's deduction and the Roth IRA's limit in both cases. The income itself is masked.

A change of job

taxtrace jobchange --year 2026 --confirm leave=2026-12-11 --confirm start=2026-12-14 --confirm new_salary=196,000
taxtrace jobchange --year 2026 --confirm loan=12,000 --confirm loan_repaid=no   # what's kept stays for the next run

Two employers in a year change four things, and neither payroll knows about the other. The 401(k)'s limit is one limit across both plans. Social Security stops at the wage base at each employer, so the new one withholds again, and what's past the base comes back as a credit on Schedule 3 line 11. A 401(k) loan comes due on leaving: what's unpaid is taxed, with 10% more under age 59½, unless it's repaid or the same amount is rolled over by October 15 of the next year. And a bonus, a sign-on or a paid-out vacation is withheld at a flat 22%, whatever your bracket.

jobchange puts the year as it stands beside the year with the change, from the latest pay stub and last year's other income. The cases are rough on purpose, without capital gain rates or credits: they're for comparing, and the difference is what to read. Leaving after December 31 changes nothing on the year's return, and it says so. The terminal gets the paychecks left and what changes, with the amounts masked.

Stock sales

taxtrace 1099 2026                                   # reads the 1099-B on a consolidated statement too
taxtrace sales --year 2026 trades.csv                # Schedule D's totals, and any purchases in the wash-sale windows
taxtrace sales --year 2026 --confirm realized_short=-1,700   # before the 1099-B comes, from the broker's realized page
taxtrace sales --year 2026 trades.csv --confirm loss_ACME_2026-10-20=yes   # a loss to watch the window of

The 1099-B's sales are read under their headings (short-term or long-term, the Form 8949 box) and columns. Each one's printed gain is checked against its proceeds and basis, and a wash sale's disallowed loss is added back. sales nets the two sides with the capital gain distributions and last year's carryovers, then applies the $3,000 limit against other income ($1,500 married filing separately): what's past it carries on, and what's under it is the room left for more losses.

A sold loss comes undone if the same thing is bought within 30 days either side, in any account, a spouse's too. A dividend reinvested counts. A purchase in an IRA loses the loss for good, since nothing adds it to the IRA's basis. Give sales a broker's trade history (CSV) and it lists what falls inside each window, without printing symbols, amounts or accounts to the terminal.

The year's moves

taxtrace moves --year 2026 --confirm plan_cap=20 --confirm rental_tax=3,000 --confirm charity=500
taxtrace moves --year 2026 --confirm done_401k=yes   # kept, and shown last

moves ranks what's still open by the dollars each takes off the year's tax at your own brackets, with its deadline: filling the 401(k) up to what the plan's percentage cap can reach in the paychecks left, stock losses up to the room sales found, the rental's property tax paid by December 31 when no escrow pays it, the IRAs ira finds deductible, and cash gifts to charity without itemizing (federal only, and only for giving you'd do anyway). Moves are stacked in a fixed order, each from the income the ones before it left, so two moves in one bracket aren't counted at a rate neither gets. jobchange's findings join the list: Social Security coming back, and what an unpaid loan would cost.

Documentation truncated — see the full README on GitHub.

Reviews

No reviews yet

Be the first to review this server!