Moltline TaxLots
Crypto cost-basis lots (FIFO/LIFO/HIFO/specific-ID), Form 8949 rows, 1099-DA diff. 5 of 8 free.
Sollte ich dies verwenden
Qualität und Sicherheit
Basierend auf einer automatisierten Analyse der Tool-Definitionen und der Einhaltung des Protokolls.
Kontextkosten
Dies ist die ungefähre Anzahl der Tokens, die jedes Mal verbraucht werden, wenn die Tools des Servers in den Kontext eines Modells geladen werden. Höhere Werte verringern die Aufmerksamkeit, die für andere Aufgaben verfügbar ist.
Installieren
Installation mit einem Klick
Fügen Sie dies Ihrer Datei `claude_desktop_config.json` hinzu:
{
"mcpServers": {
"taxlots": {
"url": "https://mcp.moltlinestudio.com/taxlots"
}
}
}Remote-Endpunkte
https://mcp.moltlinestudio.com/taxlotsstreamable-httpWas es kann
Tool-Inventar
Tools (8)
🟢parse_transactions(csv_text, source_hint, account)
Normalise an exchange CSV export into the canonical ledger rows. FREE. Supports the Coinbase transaction-history export (Transaction Type / Asset / Quantity Transacted columns), the Kraken ledgers export (txid / refid / type / asset / amount / fee) and a generic CSV with the canonical columns ts, type, asset, qty, fiat_value, fee_qty, fee_asset, fee_fiat, counter_asset, counter_qty, account, id. Typical input {"csv_text": "...", "source_hint": "coinbase"} returns {"rows": [...], "detected": "coinbase", "unrecognised": [...], "warnings": [...]}. Rows it cannot read are returned under unrecognised with the reason, never dropped silently. In every row qty is the whole amount that entered or left the account; when a fee was paid in the same asset, fee_qty is the part of qty that was the fee. Use before ledger_lint and build_lots. Not for other exchanges: convert those to the generic columns first. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "csv_text must be the CSV file contents"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"csv_text": {
"type": "string",
"description": "the CSV file contents (up to 2 MB)."
},
"source_hint": {
"default": "",
"type": "string",
"description": "coinbase, kraken or generic; empty to detect from the header."
},
"account": {
"default": "",
"type": "string",
"description": "account label to stamp on every row (defaults to the source name)."
}
},
"required": [
"csv_text"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}🟢ledger_lint(ledger)
Find the problems that break a lot build: missing values, duplicates, negative balances. FREE. Typical input {"ledger": <rows from parse_transactions>} returns {"issues": [{"severity": "error", "row": "cb12", "issue": "sell of 0.5 BTC exceeds balance 0.2 in account coinbase"}], "balances": {"coinbase": {"BTC": "0.2"}}, "counts": {...}}. Balances are running quantities per account and asset in time order, ignoring transfers' fiat values. Use after parse_transactions and before build_lots. Not a tax check: it checks the ledger's arithmetic consistency only. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"ledger": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "canonical rows (ts, type, asset, qty, fiat_value, fees, account...)."
}
},
"required": [
"ledger"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}🟢match_transfers(ledger, window_minutes, tolerance_pct)
Pair withdrawals with the deposits that received them between your own accounts. FREE. Typical input {"ledger": <rows>, "window_minutes": 1440} returns {"pairs": [{"out": "kr91", "in": "cb14", "asset": "BTC", "from": "kraken", "to": "coinbase", "network_fee": "0.0001", "minutes": 42.0}], "unmatched": {"transfer_out": [...], "transfer_in": [...]}}. A pair needs the same asset, a different account, the deposit inside the window after the withdrawal, and a quantity within tolerance_pct of the amount sent net of the fee. Use before build_lots so basis and holding period move with the coins instead of being treated as a sale. Not for transfers to third parties: those stay unmatched and should be typed gift_out or sell. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"}. Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"ledger": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "canonical rows."
},
"window_minutes": {
"default": 1440,
"maximum": 20160,
"minimum": 1,
"type": "integer",
"description": "how long after the withdrawal the deposit may land (default one day)."
},
"tolerance_pct": {
"default": 1,
"maximum": 25,
"minimum": 0,
"type": "number",
"description": "allowed quantity difference in percent after the fee (default 1)."
}
},
"required": [
"ledger"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}🟢build_lots(ledger, method, transfers, on_missing_lots, transfer_fee_policy, ...)
Build the lot inventory per account and every disposal with basis, gain and holding period. PREMIUM (license). Methods: fifo (the default rule when no specific identification is made, Treas. Reg. 1.1012-1(j)), lifo, hifo, or specific_id via a row's specific_lots {lot_id: qty}. Typical input {"ledger": <rows>, "method": "hifo", "transfers": <pairs from match_transfers>} returns {"disposals": [{"row": "cb9", "asset": "BTC", "qty": "0.5", "proceeds": "31000.00", "basis": "20000.00", "gain": "11000.00", "term": "long", ...}], "open_lots": [...], "summary": {"short_term": {...}, "long_term": {...}}}. Fees: a cash purchase's fee joins basis; a sale's or exchange's fee reduces the amount realized (1.1001-7); a network fee paid in the transferred asset is a disposal of those units (transfer_fee_policy dispose) unless you choose ignore. Transfers between your own accounts move lots with their basis and acquisition date. Use once ledger_lint reports no errors. Not tax advice: it applies the stated rules to your rows and shows its work. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "method must be fifo, lifo, hifo or specific_id"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"ledger": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "canonical rows."
},
"method": {
"default": "fifo",
"type": "string",
"description": "fifo, lifo, hifo or specific_id (rows without specific_lots fall back to fifo)."
},
"transfers": {
"default": [],
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "pairs from match_transfers ({\"out\": id, \"in\": id, ...}); empty to auto-match with the defaults."
},
"on_missing_lots": {
"default": "error",
"type": "string",
"description": "error (default), or zero_basis for lenient mode - disposals beyond the lots held get zero basis and unmatched transfer_out rows simply leave the inventory, each flagged."
},
"transfer_fee_policy": {
"default": "dispose",
"type": "string",
"description": "dispose (default) or ignore for network fees paid in the transferred asset."
},
"tax_year": {
"default": 0,
"maximum": 2100,
"minimum": 2009,
"type": "integer",
"description": "when set, only disposals in that calendar year are returned (the inventory still runs from the start)."
}
},
"required": [
"ledger"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}🟢form_8949_rows(disposals, tax_year, reporting, default_reporting, whole_dollars)
Lay the disposals out as Form 8949 rows with box categories and totals. PREMIUM (license). Typical input {"disposals": <from build_lots>, "tax_year": 2026, "default_reporting": "proceeds_only"} returns {"part_i": {"B": [rows]}, "part_ii": {"E": [rows]}, "totals": {...}}. Columns follow the form: description (a), date acquired (b), date sold (c), proceeds (d), cost or other basis (e), code (f), adjustment (g), gain or loss (h). Box: A/D when the broker reported proceeds and basis, B/E when proceeds only, C/F when no broker form - set per row in reporting {row_id: value} or for all rows with default_reporting. Use to draft the schedule from computed disposals. Not a filing: check the current form instructions. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "disposals must be a non-empty list from build_lots"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"disposals": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "rows from build_lots."
},
"tax_year": {
"maximum": 2100,
"minimum": 2009,
"type": "integer",
"description": "the calendar year of the disposals to include."
},
"reporting": {
"additionalProperties": true,
"default": {},
"type": "object",
"description": "per-row override: proceeds_and_basis, proceeds_only or none."
},
"default_reporting": {
"default": "none",
"type": "string",
"description": "proceeds_and_basis, proceeds_only or none (default)."
},
"whole_dollars": {
"default": false,
"type": "boolean",
"description": "round each row to whole dollars as the form permits."
}
},
"required": [
"disposals",
"tax_year"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}🟢reconcile_1099da(disposals, form_rows, qty_tolerance_pct, money_tolerance)
Diff the broker's 1099-DA lines against the computed disposals. PREMIUM (license). Typical input {"disposals": <from build_lots>, "form_rows": [{"asset": "BTC", "date_sold": "2026-03-04", "qty": "0.5", "proceeds": "31000", "basis": "", "account": "coinbase"}]} returns {"matched": [...], "broker_missing_basis": [...], "basis_mismatch": [...], "proceeds_mismatch": [...], "unmatched_form_rows": [...], "unmatched_disposals": [...]}. A line matches a disposal on the same account (when given), asset and sale date with quantity and proceeds inside the tolerances; several lots sold in one order are summed first. Use when the form arrives and the basis column is blank for coins that came from your own wallet. Not a substitute for the broker's statement. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "disposals must be a non-empty list from build_lots"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"disposals": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "rows from build_lots."
},
"form_rows": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "1099-DA lines: asset, date_sold, qty, proceeds, basis (may be blank), account (optional), id (optional)."
},
"qty_tolerance_pct": {
"default": 0.5,
"maximum": 10,
"minimum": 0,
"type": "number",
"description": "allowed quantity difference in percent (default 0.5)."
},
"money_tolerance": {
"default": 1,
"maximum": 1000,
"minimum": 0,
"type": "number",
"description": "allowed proceeds/basis difference in fiat units (default 1.00)."
}
},
"required": [
"disposals",
"form_rows"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}🟢wash_window_check(disposals, acquisitions, window_days)
Flag loss disposals with a repurchase of the same asset inside the window. FREE. Typical input {"disposals": <from build_lots>, "acquisitions": [{"asset": "ETH", "ts": "2026-02-10T10:00:00Z", "qty": "2"}]} returns {"flags": [{"row": "cb7", "asset": "ETH", "loss": "-410.00", "repurchases": [...]}], "rule_status": "..."}. The 30-day window before and after the sale is the one IRC 1091 uses for stock or securities; as checked on the verification date that statute had not been extended to digital assets that are not securities, so the output is a heads-up for planning, not an adjustment. Use when reviewing loss harvesting. Not a determination that any rule applies. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "disposals and acquisitions must be lists"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"disposals": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "rows from build_lots (uses asset, disposed_at, gain, row)."
},
"acquisitions": {
"items": {
"additionalProperties": true,
"type": "object"
},
"type": "array",
"description": "purchases/income rows with asset, ts, qty (ledger rows work as-is)."
},
"window_days": {
"default": 30,
"maximum": 90,
"minimum": 1,
"type": "integer",
"description": "days before and after the loss disposal to scan (default 30)."
}
},
"required": [
"disposals",
"acquisitions"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}🟢lp_position_math(deposit, current_prices, fees_earned_fiat)
Impermanent loss, hold-vs-pool value and basis split for a two-asset constant-product pool. FREE. Typical input {"deposit": {"asset_a": "ETH", "qty_a": "1", "price_a": "2000", "asset_b": "USDC", "qty_b": "2000", "price_b": "1"}, "current_prices": {"ETH": "3000", "USDC": "1"}} returns {"il_pct": "-2.02", "hold_value": "5000.00", "pool_value": "4898.98", "deposit_value": "4000.00", "basis_split": {...}}. The pool value assumes x*y=k with no fees; add fees_earned_fiat to see the net. The basis split is the deposit's fiat value at deposit, allocated by each side's share, which is the arithmetic a lot engine needs if the LP position is treated as one asset. Use for DeFi position reviews. Not a determination of whether the deposit is a taxable exchange. Errors: on invalid, missing, or malformed input this tool never raises a protocol error — it returns {"error": "<what is wrong and how to fix it>"} (for example {"error": "deposit and current_prices must be objects"}). Every call is read-only and idempotent, so after correcting the input it is always safe to retry.
Eingabe-Schema
{
"type": "object",
"properties": {
"deposit": {
"additionalProperties": true,
"type": "object",
"description": "asset_a, qty_a, price_a, asset_b, qty_b, price_b at the time of deposit."
},
"current_prices": {
"additionalProperties": true,
"type": "object",
"description": "{asset: price} for both assets now."
},
"fees_earned_fiat": {
"default": 0,
"minimum": 0,
"type": "number",
"description": "fees accrued to the position, in fiat."
}
},
"required": [
"deposit",
"current_prices"
],
"additionalProperties": false
}Ausgabe-Schema
{
"type": "object",
"additionalProperties": true
}Community
Nachweis