# Qonto MCP Integration — Design > Status: design v1 — 2026-07-19 (BINKY-WP-0005, from AWQ-010). > Goal: the company Qonto account becomes an agent-readable finance source > (balance, transactions, statements) through the sanctioned harness/MCP > lane. **Read scopes first; payments/transfers are Red lane forever.** > Credential provisioning is a single founder Red-lane step (DEC-2026-004). ## Variant decision (T01) Two Qonto MCP options exist as of 2026-07: | | Hosted connector | Self-hosted server | | --- | --- | --- | | Endpoint | `https://mcp.qonto.com/mcp` | `qonto/qonto-mcp-server` (GitHub), Docker image `qonto/qonto-mcp-server:latest` | | Auth | OAuth (user identity, Business-API scopes) | `QONTO_API_KEY` + `QONTO_ORGANIZATION_ID` env vars (from Qonto `/settings/integrations`) | | Transport | remote streamable-HTTP only | stdio (default) or `--transport streamable-http` | | Tool surface | curated subset incl. **write** tools (cards, invoicing, requests); no transfers | organization info, accounts, transaction history, business operations | | Custody fit | credentials live in the AI client's connector settings | env-name pattern — identical to email-connect | **Chosen: self-hosted `qonto/qonto-mcp-server`.** The hosted connector is exactly the "native integration" the corporate access policy forbids (OAuth grant held by claude.ai/the client, outside OpenBao custody, write tools bundled in). The self-hosted server consumes credentials only via env *names*, runs inside the harness, and rides the existing warden delivery path unchanged. **Read-only enforcement:** Qonto API keys are not scope-limited server-side, so read-only is enforced at **harness level**: tool allow-list restricted to read tools (organization, accounts, transactions, statements, attachments, labels). Card, invoicing, request and any future transfer tools are never allow-listed. This mirrors the Green/Blue tool allow-list of `scripts/rhythm-session.sh`. Any payment initiation stays founder-only in the Qonto app — Red lane forever, not an automation target. **Prerequisite check (founder, while in the dashboard — OH-2026-003):** confirm the current Qonto plan exposes API keys under `/settings/integrations`; note plan tier + monthly cost for `finance/CostRunRate.md` row 4. ## Credential lane (T02) — ops-warden/OpenBao custody Same pattern as `integrations/company-email-openbao.md` (WARDEN-WP-0028 tenants custody): | Item | Value | | --- | --- | | Mount | `tenants` | | Path | `tenants/binky/qonto/api` | | Fields | `QONTO_API_KEY`, `QONTO_ORGANIZATION_ID` | | Policy | `workload-kv-read-binky-qonto-api` (to be created, warden playbook) | | Catalog | `binky-qonto-api` (draft until provision) | | Risk | high (full-scope bank API key — read-only is harness-enforced) | ```text founder (Red lane, once) └─ bao kv put tenants/binky/qonto/api QONTO_API_KEY=@file QONTO_ORGANIZATION_ID=@file └─ OpenBao: tenants/binky/qonto/api └─ warden access binky-qonto-api --exec └─ qonto-mcp-server (env names only) → harness read tools └─ finance/CostRunRate.md + rhythm session feeds ``` ### Founder provision (Red lane — interactive human shell) ```bash # In the Qonto dashboard: /settings/integrations → create API key, note org ID umask 077 # key into /tmp/qonto.key, org id into /tmp/qonto.org — private terminal only bao kv put tenants/binky/qonto/api \ QONTO_API_KEY=@/tmp/qonto.key \ QONTO_ORGANIZATION_ID=@/tmp/qonto.org shred -u /tmp/qonto.key /tmp/qonto.org ``` The organization ID is low-secrecy but lives with the key so consumers get one fetch surface (same rule as IMAP username). **Key never in git/chat.** ## Consumer design (T03) | Consumer | Use | Cadence | | --- | --- | --- | | Finance Steward rhythm session | balance snapshot + new-transaction triage → `finance/` metadata | weekly (harness-scheduled, after cutover) | | `finance/CostRunRate.md` | resolve **TBC** rows: desk rent (HUB31 debit), Qonto plan fee; verify DATEV pass-through, railiance01 debit | first pull, then on statement events | | OH-2026-003 package | real cost-vs-usage numbers; the working MCP is itself an argument FOR keeping Qonto | once, next office hour | | Runway view (CostRunRate finding 2) | month-end balance series → liquidity awareness | monthly | Rules: - Transaction **metadata** (dates, counterparties, amounts) may land in `finance/` evidence tables; no bulk statement exports into git. - Read-only tool allow-list per above; sessions run Green/Blue. - **DUO boundary:** main accounting stays DATEV Unternehmen Online via the StB lane. Qonto MCP complements it (operational awareness, run-rate, runway); it does not replace Belegablage or bookkeeping. ## Execution checklist 1. [x] Variant + read-only enforcement decided (this doc) 2. [x] OpenBao lane designed (`tenants/binky/qonto/api`) 3. [x] DecisionQueue package prepared (DEC-2026-004) 4. [x] DEC-2026-004 **approved** (founder, 2026-07-19) 5. [x] CCR-2026-0008 + policy HCL + agent-high-risk-boundary deny (railiance-platform) 6. [x] ops-warden catalog `binky-qonto-api` **draft** + playbook (`ops-warden/wiki/playbooks/binky-qonto-api.md`) 7. [ ] **Red lane — founder (OH-2026-003):** create API key; `bao kv put` via `@file` (see founder block below and `officehour/2026-08-command-day-runbook.md`) 8. [ ] Apply CCR-2026-0008 metadata (policy + OIDC role) — platform-operator 9. [ ] Capabilities-safe verify; promote catalog draft → active 10. [ ] First read-only pull; update CostRunRate TBC rows (BINKY-WP-0005-T05) 11. [ ] Wire Finance Steward recurring session (post-cutover, harness lane — out of scope for BINKY-WP-0005 close; follow-on after T05) ## OH-2026-003 / T05 runbook (copy-paste) ### A. Founder Red lane (interactive human shell only) ```bash # 1) Qonto dashboard (browser): # - /settings/integrations → create API key # - copy organization ID # - note plan tier + monthly fee (CostRunRate row 4) # - optional while there: recent HUB31 / desk-rent debit amount (row 1) # 2) OpenBao (private terminal — never paste key into chat/agent): bao login -method=oidc -path=netkingdom # platform-admin or write-capable role umask 077 # put key into /tmp/qonto.key and org id into /tmp/qonto.org (editor / paste) bao kv put tenants/binky/qonto/api \ QONTO_API_KEY=@/tmp/qonto.key \ QONTO_ORGANIZATION_ID=@/tmp/qonto.org shred -u /tmp/qonto.key /tmp/qonto.org ``` ### B. Platform apply (after or before A — metadata only, no secret write) ```bash cd ~/railiance-platform # after platform-operator approval recorded on CCR-2026-0008: python3 scripts/credential-change.py applier-dry-run CCR-2026-0008 python3 scripts/credential-change.py applier-apply CCR-2026-0008 # re-apply agent-high-risk-boundary if that policy is live-managed separately ``` ### C. Promote + first pull (agent or human, Blue lane) ```bash # capabilities-safe (never bao kv get for deny tests) LANE=$(bao token create -policy=workload-kv-read-binky-qonto-api -ttl=2m -field=token) bao token capabilities "$LANE" tenants/data/binky/qonto/api # expect read bao token revoke "$LANE" # promote ops-warden catalog entry status: draft → active (see playbook) # then: warden access binky-qonto-api --all --exec -- \ qonto-mcp-server # read tools only: org, accounts, transactions # Update finance/CostRunRate.md rows 1 + 4 with verified amounts; # log evidence metadata (dates, counterparties, amounts) — no bulk statements in git. ``` **Harness read-only allow-list (enforce at session wire-up):** organization, accounts, transactions, statements metadata, attachments metadata, labels. Never: cards, invoicing, payment requests, transfers. ## See also - `integrations/company-email-openbao.md` — custody pattern being mirrored - `AutopilotWorkQueue.md` AWQ-010 (origin), `OfficeHourQueue.md` OH-2026-003 - `railiance-platform` CCR-2026-0008 · `ops-warden` catalog `binky-qonto-api` - Qonto docs: ,