Money Machine · Documentation

Clean Table

Deterministic CSV & Table Normalization

What it does

clean_table takes a delimited table and a schema you state — which source column becomes which output field, and of what type — and returns normalized rows against exactly that schema.

A value that cannot be read with certainty is never guessed. It is returned in a separate exceptions array with its row number, the raw source row and a plain reason. Every delivered cell is independently re-checked against its source token before the response is built, and the verification counts are returned with the data. If that check fails, nothing is returned and the payment is cancelled.

Deterministic: the same input and schema produce the same output.

Measured on 4,464 held-out rows from 8 published UK government spend files (Open Government Licence v3.0, four publishers; the held-out split was made before anything was measured): 100% field accuracy, 99.51% straight-through, 0.49% exceptions, 0 silent errors. That is a benchmark on public data, reproducible from the same files — not a guarantee about your data.

Connecting

MCP endpoint
https://money-machine.pradooskee.workers.dev/mcp
Transport
MCP over Streamable HTTP (POST). A browser GET is refused.
Tool
clean_table
Discovery
tools/list is free and unauthenticated and returns the full input schema.

Input

PropertyTypeRules
csvstring, requiredThe delimited table including its header row. 1–48,000 characters, at most 2,000 data rows. Blank lines are skipped.
fieldsarray, required1–12 entries. Each maps one source column to one output field.
fields[].fieldstring, requiredOutput field name, 1–64 characters.
fields[].columnstring, requiredSource column header, 1–128 characters, matched case-insensitively with whitespace collapsed.
fields[].typeenum, requiredtext, date, money or code — see below.
fields[].requiredbooleanDefault true. A missing value, or a missing column, sends the row to exceptions.
dedupeKeystringAn output field to deduplicate on, case-insensitively; the first occurrence is kept. Omit for no deduplication.
dateOrderenumDMY or MDY: your system's date order. The file's own evidence always wins over this.

Field types

Output

Example

Request (sent without payment, this returns the payment terms; sent with a valid payment, it returns the result):

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "clean_table",
    "arguments": {
      "csv": "Supplier,Date,Amount,Ref\nAcme Ltd,25/01/2023,\"£1,234.50\",inv-001\nBeta  Co,03/04/2023,(99.00),inv-002\nGamma plc,31/13/2023,12.5,inv-003",
      "fields": [
        {
          "field": "payee",
          "column": "Supplier",
          "type": "text"
        },
        {
          "field": "date",
          "column": "Date",
          "type": "date"
        },
        {
          "field": "amount",
          "column": "Amount",
          "type": "money"
        },
        {
          "field": "ref",
          "column": "Ref",
          "type": "code"
        }
      ]
    }
  }
}

Delivered rows and exceptions:

{
  "rows": [
    {
      "payee": "Acme Ltd",
      "date": "2023-01-25",
      "amount": 1234.5,
      "ref": "INV-001"
    },
    {
      "payee": "Beta Co",
      "date": "2023-04-03",
      "amount": -99,
      "ref": "INV-002"
    }
  ],
  "exceptions": [
    {
      "row": 4,
      "reason": "unparseable or ambiguous date \"31/13/2023\" in date",
      "raw": "Gamma plc,31/13/2023,12.5,inv-003"
    }
  ]
}

Row 3's 03/04/2023 is ambiguous on its own; row 2's 25/01/2023 proves the file is day-first, so it is read as 3 April. Row 4's month 13 cannot be a date, so the row is refused rather than repaired.

Limits

Pricing and payment

Price
$0.02 per paid call (20000 atomic units)
Network
Base mainnet (eip155:8453)
Asset
Native Circle USDC: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Pay to
0xF51ABC29be3f0Cc86F189FfC634124d08776A065
Payment
USDC via Circle Gateway / x402
  1. Call clean_table without payment. The response is an x402 v2 PaymentRequired with exactly one requirement: scheme exact, the price, network, asset and pay-to address above.
  2. Sign that requirement as an EIP-3009 authorization against Circle's GatewayWallet contract named in the requirement's extra (GatewayWalletBatched). Gateway requires the authorization to stay valid for at least 7 days (minValiditySeconds 604800).
  3. Resend the same call with the payment payload. The service verifies the payment with Circle, runs the job, re-checks every delivered cell and returns the result in the same response.
  4. Circle Gateway settles payments in batches, so a paid call has no transaction hash of its own when it is served; the sale is identified by its payment reference and reconciled to a batch transaction later.
  5. If the verification pass fails, nothing is returned and the payment is cancelled.

Privacy and retention

The stored output exists so that a paid response lost in transit can be delivered again without a second charge. It is the delivered result — including exception rows, which contain the raw source row.

One detail: if none of the columns named in your schema appears in the file, the call is refused and not charged, and the refusal message — which lists the column names from your schema, not any table content — is kept in the transaction record.

Errors