Girovo API
Mit Girovo API arbeitet deine App mit Girovo auf demselben Rechner. Sie liest Konten und Umsätze, ändert Kategorien, Notizen, Budgets und Einstellungen und schlägt Überweisungen vor. Jede App fragt vorher den Nutzer.
- Für
- Girovo Next 7.0, Windows und Linux
- Verbindung
- nur auf diesem Rechner
- Standard
- aus
- Protokoll
- JSON-RPC 2.0, eine Nachricht pro Zeile
Girovo API gehört zu Girovo Next, der Vorabversion von Girovo 7. Methoden und Antworten können sich bis zur Version 7.0 noch ändern.
Das Wichtigste
- Girovo API ist aus, bis der Nutzer sie einschaltet: Einstellungen › Girovo API › Girovo API zulassen.
- Es gibt kein Netzwerk und kein HTTP. Unter Windows ist es eine Named Pipe, unter Linux ein Unix Socket. Nur der angemeldete Benutzer kommt daran.
- Jede App fragt zuerst. Girovo zeigt einen Dialog mit dem Namen der App, ihrem Herausgeber und jedem Recht einzeln.
- Den Herausgeber liest Girovo aus der Codesignatur deiner App. Was die App über sich selbst sagt, zählt dafür nicht. Unsignierte Apps zeigt Girovo als „Herausgeber unbekannt“.
- Überweisungen schlägt deine App nur vor. Girovo öffnet sie ausgefüllt, der Nutzer prüft sie und sendet sie selbst, dann folgt die Freigabe der Bank.
- Der Nutzer kann jedes Recht in Einstellungen › Girovo API wieder entziehen, für jede App einzeln.
Verbinden
Öffne die Pipe oder den Socket und sende JSON-RPC 2.0, eine Nachricht pro Zeile, mit \n am Ende. Antworten und Ereignisse kommen genauso zurück.
Adresse
- Windows
\\.\pipe\girovo-api-<SID>- Linux
$XDG_RUNTIME_DIR/girovo-api.sock
Der erste Aufruf: girovo.hello
Jede Verbindung beginnt mit girovo.hello. Vorher beantwortet Girovo nichts anderes. Du nennst den Namen deiner App, die Rechte, die du brauchst, und einen kurzen Grund für den Nutzer.
{"jsonrpc":"2.0","id":1,"method":"girovo.hello","params":{"app":"Mein Haushaltsbuch","version":"1.0","permissions":["accounts.read","transactions.read"],"reason":"Zeigt deine Kontostände im Haushaltsbuch."}}Die Antwort kommt, sobald der Nutzer entschieden hat. granted sind alle Rechte, die deine App jetzt hat. Der Nutzer kann einzelne Rechte ausschalten, prüfe also granted.
{"jsonrpc":"2.0","id":1,"result":{"granted":["accounts.read","transactions.read"],"girovo":{"version":"7.0.0","api":1}}}Was der Dialog zeigt
- Symbol und Name deiner App, aus der Programmdatei, nicht aus hello.
- „Herausgeber: <Name>“ mit einem Haken, wenn Windows der Signatur vertraut. Sonst „Herausgeber: unbekannt“ als Warnung, mit dem Pfad der Datei.
- Jedes Recht als eigener Schalter. Der Nutzer kann einzelne ausschalten.
- Deinen Grund aus hello, als Worte der App gekennzeichnet.
- Zulassen und Ablehnen.
Was passieren kann
- Zugelassen
- Girovo merkt es sich, bis der Nutzer es entzieht. Ein späteres hello fragt nur nach Rechten, die fehlen.
- Abgelehnt
- refused_by_user. Danach bekommt deine App denied, bis Girovo neu startet.
- Keine Antwort
- Nach 2 Minuten timeout. Das ist keine Ablehnung, du darfst wieder fragen.
- Nicht angemeldet
- Der Aufruf wartet. Girovo kommt nach vorn und sagt bei der Anmeldung, welche App fragt. Nach 2 Minuten ohne Anmeldung kommt locked.
- Zu viel auf einmal
- busy, etwa bei mehr als 4 Verbindungen eines Programms.
Rechte
Frag nur nach dem, was deine App wirklich braucht. Fehlt später ein Recht, bekommst du not_permitted mit data.permission. Ein neues hello mit diesem Recht öffnet den Dialog nur dafür.
accounts.read- Konten, Salden, Verfügbar und den Gesamtsaldo lesen
transactions.read- Umsätze mit Notizen und Kategorien lesen und suchen
insights.read- Zahlen der Analyse, Verträge & Abos, Budgets und Sparziele lesen
ask- Girovo AI fragen (noch keine Methode)
categories.write- Kategorien von Umsätzen, Regeln und eigene Kategorien
notes.write- Notizen an Umsätzen
budgets.write- Monatsbudgets, Sparziele, Erinnerungen und Namen von Verträgen
settings.read- Einstellungen lesen
settings.write- Einstellungen ändern, nur die freigegebenen
bank.refresh- Neue Daten von der Bank holen. Fragt die Bank nach einer Freigabe, gibt der Nutzer sie in Girovo.
transfers.request- Überweisungen und Terminüberweisungen vorschlagen. Der Nutzer prüft und sendet jede in Girovo.
Methoden
Alle Methoden beginnen mit girovo. Beträge sind ganze Cent mit Währung, etwa {"cents":1299,"currency":"EUR"}. Tage sind yyyy-mm-dd, Monate yyyy-mm. Konten, Umsätze und Verträge haben eigene IDs aus den Lese-Methoden.
Lesen
girovo.accounts.list{}{ accounts[], total[] }: jedes Konto mit id, name, type, iban, bank, balance und available, dazu der Gesamtsaldo je Währung.
girovo.transactions.list{ account?, from?, to?, query?, category?, limit?, cursor? }{ transactions[], next? }: Umsätze, neueste zuerst. limit 1 bis 500, Standard 100. next ist der cursor für die nächste Seite.
girovo.insights.month{ month? }Einnahmen, Ausgaben, Saldo und beide nach Kategorie für einen Monat, Standard dieser Monat. coverage sagt, ob der Monat ganz geladen ist.
girovo.contracts.list{}{ contracts[] }: Verträge & Abos mit Betrag pro Monat und Jahr, letztem und nächstem Tag.
girovo.budgets.list{ month? }{ month, coverage, budgets[] }: jedes Monatsbudget mit Ausgaben, Rest und state (left, exact, over, unknown).
girovo.goals.list{}{ goals[] }: Sparziele mit Ziel, Stand und was noch fehlt.
Ändern
girovo.categories.set{ booking, category | null }{ booking, category }. null setzt den Umsatz zurück auf die Regel oder den Vorschlag.
girovo.rules.add{ booking, category } | { payee, category }{ applied, payees[], … }. Hat der Nutzer den Empfänger von Hand eingeordnet, bleibt es dabei: applied false, reason filed_by_hand.
girovo.categories.create{ name, direction?: "out" | "in" }{ category: { id, name }, direction }
girovo.notes.set{ booking, text | null }{ booking, note }. Eine Zeile. null oder leer löscht die Notiz.
girovo.budgets.set{ category, cents | null }{ category, cents }. Nur für Ausgabenkategorien. null löscht das Budget.
girovo.goals.set{ account, name, target | null, by? }{ account, goal }. Nur für Sparkonten, by als yyyy-mm. Wo Sparziele Girovo Plus brauchen, kommt not_permitted.
girovo.reminders.set{ contract, by | null, lead?: 7 | 14 | 30 }{ contract, reminder }. Eine Erinnerung an einen Vertrag, lead Tage vorher.
girovo.contracts.rename{ contract, name | null }{ contract, name, own }. null stellt den erkannten Namen wieder her.
Einstellungen
girovo.settings.get{}{ settings, onlyOn[], onlyOff[] }: die Einstellungen, die deine App lesen und ändern kann. onlyOn und onlyOff nennen die, die nur in eine Richtung gehen.
girovo.settings.set{ key, value }{ key, value, changed }. Andere Schlüssel geben invalid.
Freigegebene Schlüssel: language, theme, blackBackground, idleMinutes (5, 10, 15, 30), balancesAtLogin, bookingsAtLogin, keepBalances und keepBookings (nur an), companyLogos (nur aus), ai, aiTone, aiLength, aiUseName, aiNames, singleKeyShortcuts, accountOrder, accountGrouping (type, bank, none), hiddenAccounts.
Bank und Überweisungen
girovo.bank.refresh{ account? }{ accounts: [{ account, state, newBookings?, balance? }], newBookings }. Holt neue Daten wie Girovo selbst. Eine Freigabe gibt der Nutzer in Girovo. Kann bis 10 Minuten dauern.
girovo.transfers.request{ iban, name, cents, purpose?, executeOn?, account? }{ request, state: "pending" }. Girovo öffnet die Überweisung ausgefüllt, mit „Angefragt von <App>“. Mit executeOn wird es eine Terminüberweisung, wenn das Konto sie anbietet.
girovo.transfers.status{ request }{ request, state, text?, changed? }. Nur für eigene Anfragen.
state ist pending, bis der Nutzer handelt. Dann sent (die Bank hat sie angenommen), refused (ohne Senden geschlossen), failed (die Bank hat abgelehnt, ihre Worte in text) oder unclear (noch offen, ob sie durchging). changed: true heißt, der Nutzer hat andere Werte gesendet. Welche, sagt Girovo nicht. Das Ergebnis kommt auch als Ereignis girovo.transfer.updated auf der Verbindung, die gefragt hat.
Ereignisse
girovo.events.subscribe{ kinds[] }{ subscribed[] }
girovo.events.unsubscribe{ kinds[]? }{ subscribed[] }. Ohne kinds enden alle Abos dieser Verbindung.
Fehler
Ein Fehler ist ein JSON-RPC-Fehler. error.data.reason ist der Code aus dieser Liste, dazu kommen Felder wie permission, param oder text. Die message ist für dein Log gedacht, nicht für deine Oberfläche.
{"jsonrpc":"2.0","id":2,"error":{"code":-32003,"message":"This app does not have the permission for this method.","data":{"reason":"not_permitted","permission":"insights.read"}}}lockedGirovo ist gesperrt oder niemand ist angemeldet. Versuch es später wieder.deniedDer Nutzer hat deine App abgelehnt. Bis Girovo neu startet, gilt das für alles.not_permittedDeiner App fehlt ein Recht, data.permission nennt es. Ohne data.permission sagt message den Grund, etwa zu viele offene Überweisungen.refused_by_userDer Nutzer hat im Dialog oder bei der Freigabe abgelehnt.bank_errorDie Bank hat einen Fehler gemeldet, ihre Worte in data.text.timeoutKeine Antwort rechtzeitig, etwa auf den Dialog. Du darfst wieder fragen.rate_limitedZu viele Aufrufe in kurzer Zeit.too_largeDie Nachricht ist größer als 1 MB.busyZu viele Verbindungen oder wartende Aufrufe.invalidEin Parameter passt nicht, data.param nennt ihn. Auch jeder Aufruf vor hello.method_not_foundDiese Methode gibt es nicht.internalGirovo konnte den Aufruf nicht beantworten.
Ereignisse
Mit girovo.events.subscribe hört deine Verbindung auf Ereignisse. Sie kommen als JSON-RPC-Benachrichtigung ohne id, mit der Methode girovo.<Art>. Jede Art braucht ein Recht. Entzieht der Nutzer es, enden ihre Ereignisse sofort. Ein Abo gilt nur für diese Verbindung.
→ {"jsonrpc":"2.0","id":3,"method":"girovo.events.subscribe","params":{"kinds":["bookings.new","balances.changed"]}}
← {"jsonrpc":"2.0","id":3,"result":{"subscribed":["bookings.new","balances.changed"]}}
← {"jsonrpc":"2.0","method":"girovo.balances.changed","params":{"account":"a_…","balance":{…},"available":{…}}}bookings.new{ account, count, bookings[] }Neue Umsätze auf einem Konto, das schon geladen war.
balances.changed{ account, balance, available }Ein Saldo hat sich geändert.
transfer.updated{ request, state, text?, changed? }Eine Überweisungsanfrage deiner App ist entschieden.
Beispiel in Node.js
Verbinden, hello, Konten lesen. Kein Paket nötig, Node 18 oder neuer reicht. Girovo muss laufen und Girovo API muss an sein.
// girovo-client.mjs: node girovo-client.mjs
import net from 'node:net'
import { execFileSync } from 'node:child_process'
function address() {
if (process.platform === 'win32') {
// "PC\\name","S-1-5-21-…"
const line = execFileSync('whoami', ['/user', '/fo', 'csv', '/nh'], { encoding: 'utf8' })
const sid = line.trim().split(',').pop().replaceAll('"', '')
return '\\\\.\\pipe\\girovo-api-' + sid
}
return process.env.XDG_RUNTIME_DIR + '/girovo-api.sock'
}
const socket = net.connect(address())
socket.setEncoding('utf8')
const waiting = new Map()
let nextId = 1
let buffer = ''
function call(method, params = {}) {
const id = nextId++
socket.write(JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n')
return new Promise((resolve, reject) => waiting.set(id, { resolve, reject }))
}
socket.on('data', (chunk) => {
buffer += chunk
let at
while ((at = buffer.indexOf('\n')) >= 0) {
const line = buffer.slice(0, at)
buffer = buffer.slice(at + 1)
if (!line.trim()) continue
const message = JSON.parse(line)
if (!('id' in message)) continue // an event
const { resolve, reject } = waiting.get(message.id)
waiting.delete(message.id)
if (message.error) reject(message.error)
else resolve(message.result)
}
})
socket.on('connect', async () => {
try {
const hello = await call('girovo.hello', {
app: 'Mein Haushaltsbuch',
version: '1.0',
permissions: ['accounts.read'],
reason: 'Zeigt deine Kontostände im Haushaltsbuch.',
})
console.log('Erlaubt:', hello.granted)
const { accounts } = await call('girovo.accounts.list')
for (const a of accounts) console.log(a.name, a.balance?.cents, a.balance?.currency)
} catch (error) {
console.error(error.data?.reason, error.message)
} finally {
socket.end()
}
})Girovo MCP
Girovo MCP verbindet KI-Assistenten wie Claude Desktop oder Codex mit Girovo. Es ist ein MCP-Server über stdio, der Girovo API nutzt. Der Assistent bekommt dieselben Dialoge und Rechte wie jede andere App.
Wo es liegt
- Windows
%LOCALAPPDATA%\Programs\Girovo\girovo-mcp.exe- Linux (deb)
/usr/bin/girovo-mcp- Linux (AppImage)
~/.config/Girovo/girovo-mcp
Claude Desktop
Trag Girovo MCP in claude_desktop_config.json ein. Unter Windows liegt die Datei in %APPDATA%\Claude. Schreib den vollen Pfad aus und verdopple in JSON jeden Backslash.
{
"mcpServers": {
"girovo": {
"command": "C:\\Users\\DEIN-NAME\\AppData\\Local\\Programs\\Girovo\\girovo-mcp.exe"
}
}
}Unter Linux ist command der volle Pfad, etwa "/usr/bin/girovo-mcp". Starte den Assistenten danach neu.
Andere MCP-Clients
Für Codex und andere Clients gilt dasselbe: Der Befehl ist der Pfad zu girovo-mcp, ohne Argumente.
So verhält es sich
- Beim ersten Werkzeug fragt Girovo MCP nach accounts.read, transactions.read und insights.read, dazu nach dem Recht dieses Werkzeugs. Ein Dialog deckt so den Anfang ab.
- Braucht ein späteres Werkzeug ein weiteres Recht, öffnet Girovo den Dialog nur dafür.
- Unter Windows zeigt der Dialog den Assistenten, etwa „Claude (Anthropic PBC) über Girovo MCP“. Unter Linux zeigt er Girovo MCP mit seinem Pfad.
- Ist Girovo zu oder Girovo API aus, sagt das Werkzeug das. Der nächste Aufruf verbindet neu.
Die 19 Werkzeuge
list_accountsaccounts.listaccounts.readsearch_transactionstransactions.listtransactions.readmonth_summaryinsights.monthinsights.readlist_contractscontracts.listinsights.readlist_budgetsbudgets.listinsights.readlist_savings_goalsgoals.listinsights.readset_booking_categorycategories.setcategories.writeadd_category_rulerules.addcategories.writecreate_categorycategories.createcategories.writeset_notenotes.setnotes.writeset_budgetbudgets.setbudgets.writeset_savings_goalgoals.setbudgets.writeset_reminderreminders.setbudgets.writerename_contractcontracts.renamebudgets.writeget_settingssettings.getsettings.readset_settingsettings.setsettings.writerefresh_from_bankbank.refreshbank.refreshrequest_transfertransfers.requesttransfers.requesttransfer_statustransfers.statustransfers.request
Läuft dein Assistent in der Cloud, geht alles, was er aus Girovo liest, an seinen Anbieter.
Grenzen
Was Girovo zulässt
- Verbindungen pro Programm
- 4 (16 insgesamt)
- Erster Aufruf nach dem Verbinden
- innerhalb von 30 s
- Aufrufe pro Sekunde
- 20, kurz bis 40
- Offene Aufrufe pro Verbindung
- 32
- Größe einer Nachricht
- 1 MB
- Antwort auf einen Aufruf
- bis 150 s
- girovo.bank.refresh
- bis 10 Minuten
- Warten auf die Anmeldung
- 2 Minuten, höchstens 64 Aufrufe
- Offene Überweisungen
- 3 pro App, 10 insgesamt
Was keine App kann
- PIN, Windows Hello und Sicherheitsschlüssel
- „Weitere Banken mit anmelden“ und das Gerät vergessen
- Gespeicherte Daten löschen oder zurücksetzen, ein Backup wiederherstellen
- Girovo API selbst: den Schalter und die Rechte, auch nicht die eigenen
- Update-Kanal und Updates
- Nutzungsdaten, „Neue Umsätze melden“ und die Synchronisierung
- Eine Überweisung senden: das tut immer der Nutzer in Girovo
Girovo ist source available unter der PolyForm Perimeter License 1.0.1. Den Quellcode findest du auf GitHub.