# Bank Statement PDF to CSV/Excel, Balance-Verified (MCP server) (`doubleaigents/bank-statement-to-csv-mcp`) Actor

Deterministic MCP tool for AI agents: bank statement PDF/scan to CSV + XLSX of transactions, with every row's running balance and opening + transactions = closing reconciled and a verified flag. No LLM inside.

- **URL**: https://apify.com/doubleaigents/bank-statement-to-csv-mcp.md
- **Developed by:** [Double AIgents](https://apify.com/doubleaigents) (community)
- **Categories:** AI, MCP servers, Developer tools
- **Features:** Limited permissions, Single-tenant, Server interface
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 statement page processeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bank Statement PDF to CSV/Excel, Balance-Verified (MCP server)

A deterministic bank statement converter for AI agents, served as an MCP server. There is no LLM inside,
so the same file gives the same output every time. It runs on CPU and does not call any paid API.

**Use it for:** bookkeeping and accounts imports, affordability and lending checks, audit and reconciliation work,
expense categorisation pipelines, and turning a year of PDF statements into one spreadsheet.

**Why agents pick it:** a statement converter that silently drops or mis-signs one row gives you a spreadsheet
that looks fine and is wrong. This tool proves it: every row is checked against the bank's own running balance
(previous balance + credit - debit = stated balance), and the whole statement is checked as opening + credits -
debits = closing. Your agent gets a plain `verified` flag, and the failing rows if there are any.

| Tool | What your agent gets back |
|---|---|
| `bank_statement_to_csv` | `transactions`: date (ISO), date_raw, description (multi-line descriptions joined), debit, credit, signed amount, stated balance, computed balance and `balance_ok` per row. `opening_balance`, `closing_balance`, `total_credits`, `total_debits`, `currency`, `checks` and `verified`. Plus a CSV and an XLSX with **Transactions** and **Checks** sheets, failing rows in red. |

Handles separate Debit/Credit (Paid out/Paid in, Withdrawal/Deposit) columns, single signed Amount columns, sign
from CR/DR suffixes or from the balance movement, US and UK date order (decided per statement), dates printed once
per day, descriptions above or below the amount line, repeated headers on each page, and US-style statements split
into Deposits / Withdrawals / Checks sections (each section total is checked too). Diagonal "SAMPLE"/"COPY" watermarks
are ignored. Scanned statements are OCR'd with Tesseract.

### Connect

MCP endpoint (streamable HTTP):

```
https://doubleaigents--bank-statement-to-csv-mcp.apify.actor/mcp
Authorization: Bearer <APIFY_TOKEN>
```

Claude Desktop / Cursor style config:

```json
{ "mcpServers": { "bank-statements": {
    "url": "https://doubleaigents--bank-statement-to-csv-mcp.apify.actor/mcp",
    "headers": { "Authorization": "Bearer <APIFY_TOKEN>" } } } }
```

### Tool inputs

`bank_statement_to_csv(file_url | file_base64, filename?, lang="eng")`

- Send exactly one of `file_url` (public http/https) or `file_base64`. Supported files are PDF, PNG, JPG, TIFF, BMP and WEBP, up to 50 MB and 500 pages.
- The CSV and XLSX come back as key-value store URLs. Files under 8 MB also come back inline as base64.

### Pricing (pay per event)

| Event | USD |
|---|---|
| `page-processed`: each page of the input statement, after extraction and reconciliation | 0.03 |

You are charged only after a call completes. If your run's maximum charge cannot cover the page count, the call is refused before any work is done.

### Limits worth knowing

- `verified: false` means a figure does not tie out: a misread, a row the layout hid, or a statement that is itself inconsistent. The failing check is named in `checks` and `problems`.
- The opening balance is read from the statement ("Opening/Beginning balance", "Balance brought forward"). If none is printed, it is derived from the first row and marked `derived-from-first-row`.
- Credit card statements without a running balance are checked on totals only.
- Handwriting is not supported. Poor scans lower OCR accuracy; the balance check is what flags it.

### Batch mode

You can also run the Actor normally with `fileUrl` (or a list in `fileUrls`). It writes one dataset item per statement with the totals, checks, links to the CSV and XLSX, and the transactions.

### Who runs it

Double AIgents Ltd, UK (company no. 17513072). Your input files are processed for the call. Outputs sit in the run's Apify storage, which Apify removes under its data-retention policy.
Need volume pricing, a private deployment or a custom document pipeline? https://www.doubleaigents.com

### More tools from Double AIgents

- [PDF Tables to Excel + True PII Redaction](https://apify.com/doubleaigents/pdf-tables-and-true-redaction-mcp) — tables from PDFs and scans to XLSX with every figure double-read, and true redaction of personal data with a verification log.
- [Invoice & Receipt to JSON + Excel](https://apify.com/doubleaigents/invoice-receipt-to-json-mcp) — supplier, dates, VAT number, line items and net/VAT/gross, with the totals reconciled.
- [PDF Compare](https://apify.com/doubleaigents/pdf-compare-mcp) — every added, removed, changed or moved passage between two PDF versions, plus an annotated diff PDF.

# Actor input Schema

## `fileUrl` (type: `string`):

Public http(s) URL of a bank statement (PDF, scanned PDF, PNG, JPG or TIFF; max 50 MB, 500 pages).

## `fileUrls` (type: `array`):

Process several files in one run, one dataset item each. If set, fileUrl is ignored.

## `lang` (type: `string`):

Tesseract language code for scanned pages. The image ships with eng.

## Actor input object example

```json
{
  "fileUrl": "https://mammoth.io/samples/sample-bank-statement.pdf",
  "fileUrls": [],
  "lang": "eng"
}
```

# Actor output Schema

## `results` (type: `string`):

One row per statement: transaction count, opening/closing balance, totals, the reconciliation checks, verified flag, links to the CSV and XLSX, and the transactions themselves.

## `files` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "fileUrl": "https://mammoth.io/samples/sample-bank-statement.pdf"
};

// Run the Actor and wait for it to finish
const run = await client.actor("doubleaigents/bank-statement-to-csv-mcp").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "fileUrl": "https://mammoth.io/samples/sample-bank-statement.pdf" }

# Run the Actor and wait for it to finish
run = client.actor("doubleaigents/bank-statement-to-csv-mcp").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "fileUrl": "https://mammoth.io/samples/sample-bank-statement.pdf"
}' |
apify call doubleaigents/bank-statement-to-csv-mcp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,doubleaigents/bank-statement-to-csv-mcp"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/0q72ZGTfB3fGxMqwx/builds/XCOIVPeK73YzoUfHK/openapi.json
