fints-cli: Doku-Auszug
Das ist der öffentliche Teil der deutschen README. Die vollständige README, die Sicherheitshinweise und das Änderungsprotokoll liegen im privaten Repository, zu dem Sie mit dem Kauf Zugang bekommen.
Installation
Voraussetzungen: Python 3.12 oder neuer (getestet mit 3.12, 3.13 und 3.14) und uv oder pipx. Getestet unter Linux. Kein Compiler nötig.
fints-cli wird pro Kauf lizenziert, das Repository ist privat. Nach dem Kauf
bekommen Sie eine Einladung zu github.com/sofatools/fints-cli - nehmen Sie
sie an (GitHub schickt sie per E-Mail und zeigt sie auf github.com). Ein
öffentliches PyPI-Paket gibt es nicht.
1. Git Zugriff auf das private Repository geben - eine der beiden Arten:
- GitHub CLI (am einfachsten):
gh auth login, danachgh auth setup-git. Ab dann nutzt git - und damit uv und pipx - Ihre GitHub-Anmeldung fürhttps://github.com/.... - Ein SSH-Schlüssel in Ihrem GitHub-Konto: dann die
git+ssh://-URL unten.
2. Den Befehl fints installieren:
uv tool install git+https://github.com/sofatools/fints-cli
fints --version
Alternativen:
uv tool install git+https://github.com/sofatools/fints-cli@0.1.0 # feste Version
uv tool install git+ssh://git@github.com/sofatools/fints-cli # per SSH
pipx install git+https://github.com/sofatools/fints-cli # mit pipx
Findet Ihre Shell fints danach nicht, uv tool update-shell (bzw.
pipx ensurepath) ausführen und ein neues Terminal öffnen.
Aktualisieren: uv tool upgrade fints-cli (pipx: pipx reinstall fints-cli).
Was sich geändert hat, steht in CHANGELOG.md.
Aus einem Klon, zum Entwickeln: git clone https://github.com/sofatools/fints-cli,
dann uv sync && uv run pytest, oder uv tool install ., um diesen Stand zu
installieren.
Produkt-ID (Pflicht)
FinTS verlangt, dass sich jedes Kundenprogramm mit einer Produkt-ID ausweist. Die ID ist an die registrierende Person oder Firma gebunden und wird deshalb nicht mitgeliefert - Sie registrieren Ihre eigene. Die Registrierung bei der Deutschen Kreditwirtschaft ist kostenlos:
- https://www.fints.org/de/hersteller/produktregistrierung öffnen und das Registrierungsformular ausfüllen (Produktname, Name und Anschrift, kurze Beschreibung wie „privater, nur lesender Kontozugriff”).
- Das Formular per E-Mail an registrierung@hbci-zka.de schicken.
- Nach etwa 10-15 Werktagen bekommen Sie Ihre Registrierungsnummer. Im FinTS-Sprachgebrauch ist das die „Produktbezeichnung”, die der Client an die Bank schickt.
- In der Umgebung exportieren, in der
fintsläuft:
export FINTS_PRODUCT_ID="0123456789ABCDEF012345678" # 25 Zeichen
Ohne FINTS_PRODUCT_ID bricht das Werkzeug mit einem Hinweis auf diesen
Abschnitt ab.
Konfiguration
~/.config/fints-cli/config.toml ($XDG_CONFIG_HOME wird beachtet;
--config oder FINTS_CONFIG überschreiben den Pfad). Eine Tabelle pro Bank:
[banks.gls]
blz = "43060967"
url = "https://fints1.atruvia.de/cgi-bin/hbciservlet"
login = "1234567890"
pin_env = "FINTS_PIN_GLS"
# or: pin_command = "pass show banking/gls/pin"
tan = "auto" # auto | decoupled | manual
# tan_mechanism = "946" # optional: security function id, see `fints login`
blz,url,login: Bankleitzahl, FinTS-Server-URL (muss mithttps://beginnen) und Ihr Online-Banking-Login (oft Kontonummer oder Alias). Unbekannte Schlüssel werden gemeldet, ein Tippfehler fällt also auf.- PIN: genau eines von
pin_env(Name einer Umgebungsvariable mit der PIN) oderpin_command(ein Shell-Kommando, dessen erste Ausgabezeile die PIN ist, z. B.pass show banking/gls/pin). Die PIN wird nie auf die Platte geschrieben, nie geloggt und steht nie in einer Fehlermeldung. tan:auto(Standard): Freigabe in der App, wenn die Bank das anbietet, sonst Abfrage einer getippten TAN;decoupled: nur App-Freigabe akzeptieren, Abbruch wenn die Bank eine getippte TAN will;manual: kein Polling; Sie drücken Enter, nachdem Sie in der App bestätigt haben (braucht ein Terminal; hat die App noch nicht bestätigt, wird erneut gefragt).
tan_mechanism: eine Sicherheitsfunktion fest vorgeben.fints loginzeigt die Kennungen und Namen, die die Bank anbietet.
Bei mehreren Banken in der Datei bekommt jeder Befehl --bank <name>
(fints balance --bank gls oder fints --bank gls balance). Der
Bankname wird Dateiname im Session-Cache, also nur Buchstaben, Ziffern, -
und _.
Benutzung
fints accounts # IBAN, BIC, Kontonummer, Bank
fints accounts --format json
fints balance # alle Konten
fints balance DE00430609670000009600 --format json
fints transactions # letzte 30 Tage, CSV
fints transactions --since 2026-01-01 --until 2026-03-31 --format json
fints transactions DE00430609670000009600 --since 2026-07-01 --format ledger
fints transactions --format beancount --account "Assets:Bank:{bank}"
fints login # neue Freigabe erzwingen, TAN-Verfahren zeigen
fints mcp # MCP-Server auf stdio
CSV-Spalten: booking_date, value_date, amount, currency, counterparty, counterparty_iban, purpose, reference, iban, posting_text. JSON hat dieselben
Felder; Beträge sind Zeichenketten ("-514.22"), damit keine Genauigkeit
verloren geht.
Daten im Format JJJJ-MM-TT. --account ist eine Vorlage für die
Kontobezeichnung in Ledger/Beancount; {iban} und {bank} werden ersetzt ({bank} in Großbuchstaben, z. B.
Assets:Bank:GLS, weil Beancount-Kontonamen mit einem Großbuchstaben beginnen müssen).
Unbekannte Gegenkonten heißen Expenses:Unknown / Income:Unknown zum
Nachbearbeiten.
Exit-Codes: 0 ok, 1 Bank- oder Netzfehler, 2 Nutzungs- oder
Konfigurationsfehler, 3 Freigabe nötig (in der App bestätigen und den Befehl
erneut ausführen), 130 abgebrochen (Strg-C).
Verlangt die Bank eine Freigabe, meldet die CLI Waiting for approval in your banking app: ... auf stderr und fragt bis zu fünf Minuten lang nach.
Daten gehen nach stdout, Meldungen nach stderr; fints transactions --format json > juli.json ergibt also eine saubere Datei. -v / --verbose (vor oder
nach dem Befehl: fints -v balance) zeigt zusätzlich die Hinweise der Bank
(Dialog response: 3060 - ...) und bei unerwarteten Fehlern den Traceback.
PIN und TAN stehen nie darin.
Antwortet die Bank nicht, gibt das Werkzeug nach 20 s (Verbindungsaufbau) bzw. 120 s (Antwort) auf, statt zu hängen.
MCP-Server
fints mcp bietet drei Tools über stdio an, alle als nur lesend markiert
(readOnlyHint): list_accounts, get_balance(iban?),
get_transactions(since, until?, iban?). Jedes nimmt optional bank.
Claude Code:
claude mcp add fints -e FINTS_PRODUCT_ID=Ihre-Registrierungsnummer -- "$(which fints)" mcp
(Mit -s user steht er in jedem Projekt zur Verfügung, nicht nur im aktuellen.)
Claude Desktop (claude_desktop_config.json) und andere MCP-Clients - den
absoluten Pfad des fints-Programms angeben, grafische Programme kennen den
PATH Ihrer Shell nicht; which fints zeigt ihn:
{
"mcpServers": {
"fints": {
"command": "/home/sie/.local/bin/fints",
"args": ["mcp"],
"env": {
"FINTS_PRODUCT_ID": "Ihre Registrierungsnummer"
}
}
}
}
Für die PIN pin_command in der config.toml verwenden (zum Beispiel
pin_command = "pass show banking/gls/pin"), damit der Passwortmanager sie zur
Laufzeit liefert. Die PIN nicht in den env-Block schreiben:
MCP-Client-Konfigurationen sind Klartextdateien, oft zwischen Rechnern geteilt
oder in ein Repository eingecheckt. Wer pin_env nutzen muss, setzt die
Variable in der Umgebung, die den MCP-Client startet, nicht in dessen
Konfigurationsdatei.
Mit "args": ["--config", "/pfad/zur/config.toml", "mcp"] liegt die
Konfiguration woanders, --bank wählt eine Bank vor. tan = "manual" lässt
sich über MCP nicht bedienen (niemand drückt Enter); für solche Banken auto
verwenden.
Verlangt die Bank eine Freigabe, blockiert das Tool nicht. Es antwortet sofort mit
{"status": "approval_needed", "message": "Approval needed: confirm the request in your banking app, then call this tool again."}
während die Bankabfrage im Hintergrund weiter wartet (bis zu fünf Minuten).
In der App bestätigen, das Tool erneut aufrufen, und das Ergebnis kommt. Ist
die Freigabe abgelaufen, startet der nächste Aufruf eine neue. Ein zweiter
Aufruf für dieselbe Bank, während der erste noch läuft (ohne auf eine Freigabe
zu warten), bekommt {"status": "busy", ...}: ein paar Sekunden später erneut
aufrufen. Pro Bank gibt es nie mehr als einen Dialog gleichzeitig - und damit
nie mehr als eine Push-Freigabe.
Fehler (falsche PIN, Bank nicht erreichbar, unbekannte IBAN, Konfigurationsprobleme) kommen als Tool-Fehler mit einer einzeiligen Meldung zurück. Weist die Bank die PIN zurück, schickt der Server diese PIN nicht noch einmal, bis er neu gestartet wird oder sich die PIN ändert - ein Agent, der den Aufruf wiederholt, kann Ihren Online-Banking-Zugang nicht sperren.
Ob ein KI-Agent Ihre Bankdaten sehen darf, entscheiden Sie: Die Tools können kein Geld bewegen, legen aber Salden und Umsätze gegenüber allem offen, was die MCP-Ausgabe liest.
Die 90-Tage-Regel
Nach PSD2 verlangen Banken für den Kontozugriff mindestens alle 90 Tage eine
neue starke Authentifizierung. In der Praxis: Hin und wieder fragt ein Aufruf
trotz warmem Session-Cache wieder nach einer Freigabe. In der App bestätigen
und den Befehl erneut ausführen. fints login erzwingt das absichtlich - es
löscht die gespeicherte Session und öffnet einen frischen Dialog.
Der Session-Cache liegt in ~/.local/state/fints-cli/<bank>.session
($XDG_STATE_HOME wird beachtet). Er enthält die Parameterdaten der Bank und
Ihre Kontenliste - nicht die PIN - und wird mit Rechten 0600 geschrieben.
Die Datei zu löschen ist immer unschädlich.
Fehlersuche
| Meldung | Was tun |
|---|---|
FINTS_PRODUCT_ID is not set |
Produkt-ID exportieren, siehe oben. |
environment variable FINTS_PIN_GLS ... is not set |
Variable exportieren oder pin_command nutzen. |
bank 'gls' rejected the login: wrong PIN or login ... |
login und PIN prüfen. Nicht blind wiederholen - Banken sperren den Zugang nach wenigen Fehlversuchen. |
cannot reach bank ... host name not found / connection refused / no answer within ... |
Netz weg oder Tippfehler in url. |
Approval needed: not confirmed within 300 s |
Befehl erneut ausführen und in der App bestätigen. |
the bank asks for a TAN to type, but this bank is configured with tan = "decoupled" |
tan = "auto" setzen. |
alles mit unexpected |
Mit -v erneut ausführen und ein Issue mit der Ausgabe eröffnen (sie enthält keine PIN). |
Quelle: fints-cli README.de.md, release 0.1.0, commit 117fd72