Skip to main content
Moneyline
All articles
Engineering5 min read

Why we open-sourced the entire document intelligence stack

Every parser, every extraction pipeline, and the MCP server, under MIT. What that decision cost us, and what it bought.

The Moneyline team · Engineering
View as .md
Analytics dashboard showing page-load and bounce-rate charts

Document intelligence is sold as a black box. You upload a bank statement, a number comes back, and the vendor tells you it is 99% accurate. When it is wrong, and it is wrong often enough to matter, you have no way to find out why. You file a support ticket and wait.

We shipped the whole stack under MIT instead: 37 parsers, the extraction pipelines behind them, the enrichment layer, the rules engine, and the MCP server. Not a community edition. Not an open core with the useful parts held back. The thing we run in production.

The argument for the black box

The case against open-sourcing this is real, and it is worth stating properly before dismissing it. Parsers are the product. A competitor can read packages/parsers/bank-statement and ship it. A customer can self-host and stop paying. The moat, if there is one, is the code.

We think that reasoning inverts the actual risk. The moat was never the parsing logic, which is a few thousand lines of well-understood layout analysis. It is the corpus of edge cases behind it: the 1,400 statement layouts we have seen fail, the check-ordering quirk in one regional bank, the fact that a specific credit union prints negative balances without a sign. That knowledge lives in test fixtures and in the people who wrote them, and neither is copied by cloning a repository.

What "entire" means

Open-core vendors use "open source" to mean the SDK. We mean the pipeline. Concretely, the repository contains:

  • Every one of the 37 document parsers, including the tax-form family that took the longest to build.
  • The classification models and the training pipeline that produces them.
  • The enrichment layer: categorization taxonomy, income verification, entity resolution.
  • The rules engine and the risk scoring, including the explanation generator.
  • The MCP server, the CLI, and all three SDKs.
  • The Helm chart and Docker Compose files we use for our own deploys.

Reading a parser

The practical benefit is not philosophical. When a statement parses wrong, an engineer can open the parser, find the branch that mishandled it, and see the assumption in plain code rather than inferring it from output.

packages/parsers/bank-statement/columns.tstypescript
/**
 * Transaction tables are found by column geometry, not header text.
 * Roughly a third of the statements we see label the amount column with
 * something other than "Amount" ("Debits", "Withdrawals (-)", or
 * nothing at all), but nearly all right-align it and keep it last.
 */
export function findAmountColumn(rows: Row[]): Column | null {
  const candidates = columnsOf(rows).filter(
    (c) => c.alignment === 'right' && c.numericRatio > 0.8,
  );
  if (candidates.length === 0) return null;

  // Running balance, when present, is rightmost and monotonic per page.
  const rightmost = candidates.at(-1);
  if (rightmost && isRunningBalance(rightmost, rows)) {
    return candidates.at(-2) ?? null;
  }
  return rightmost ?? null;
}

That comment is the actual product. It is the kind of thing you only learn by getting it wrong on real documents, and it is invisible in an API response.

What it cost

Three things, and none of them were the ones we worried about.

  1. 01Code review got slower. Everything is public, so everything gets written as if a stranger will read it. That is a real tax on velocity and a real gain in quality.
  2. 02We had to separate configuration from logic properly, because self-hosters configure things we had hard-coded. This was overdue work that we would otherwise have kept deferring.
  3. 03Security reports arrive from people who read the source. This is the cost that looks like a benefit, and it is genuinely both.

The competitor-clones-us scenario has not happened in any form that mattered. The self-hosting scenario happened immediately and turned out to be the point: teams that would never have bought a hosted black box ran it on their own infrastructure, hit edge cases we had never seen, and sent patches.

Running it yourself

A full local stack, with the API, worker, and Postgres, is one command. There is no license key and no phone-home.

bashbash
git clone https://github.com/moneyline/moneyline
cd moneyline
docker compose up

# Parse your first document against the local API.
curl -F 'file=@statement.pdf' http://localhost:8080/v1/parse

If you run it and something parses wrong, the fix is a pull request rather than a support ticket. That is the whole argument.

Open sourceArchitectureLicensing

Keep reading

Parse your first document

Everything in this article runs on the open-source core. Clone it, or start on the hosted API.