Live custody path tenants/binky/qonto-api (API_KEY/API_USER). First read-only thirdparty pull (122 txs): desk 297.50 €/mo, Qonto plan 70.80 €/mo, main balance 2185.94 €. Evidence under finance/; workplan status finished.
6.9 KiB
Qonto MCP Integration — Design
Status: lane active — 2026-07-21 (BINKY-WP-0005 finished).
Goal: the company Qonto account becomes an agent-readable finance source (balance, transactions, statements) through the sanctioned harness/MCP / thirdparty API lane. Read scopes first; payments/transfers are Red lane forever. Credentials live attenants/binky/qonto-api(CCR-2026-0008 / 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 (live) |
| Fields | API_KEY, API_USER (login/org slug) |
| MCP env map | API_KEY→QONTO_API_KEY, API_USER→QONTO_ORGANIZATION_ID |
| Policy | workload-kv-read-binky-qonto-api |
| OIDC role | binky-qonto-api-workload-kv-read |
| Catalog | binky-qonto-api (active, resolvable) |
| Risk | high (full-scope bank API key — read-only is harness-enforced) |
Auth to Qonto thirdparty API: Authorization: <API_USER>:<API_KEY>.
founder (Red lane, once)
└─ bao kv put tenants/binky/qonto-api API_KEY=@file API_USER=@file
└─ OpenBao: tenants/binky/qonto-api
└─ warden access binky-qonto-api --exec
└─ map fields → QONTO_* env → qonto-mcp-server / curl thirdparty
└─ finance/CostRunRate.md + rhythm session feeds
Founder provision (Red lane — interactive human shell)
# In the Qonto dashboard: /settings/integrations → create API key, note login/org slug
umask 077
bao kv put tenants/binky/qonto-api \
API_KEY=@/tmp/qonto.key \
API_USER=@/tmp/qonto.user
shred -u /tmp/qonto.key /tmp/qonto.user
API_USER 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
- Variant + read-only enforcement decided (this doc)
- OpenBao lane designed → live path
tenants/binky/qonto-api - DecisionQueue package prepared (DEC-2026-004)
- DEC-2026-004 approved (founder, 2026-07-19)
- CCR-2026-0008 active (policy + OIDC role + agent-high-risk-boundary)
- ops-warden catalog
binky-qonto-apiactive + playbook - Red-lane secret present (
API_KEY+API_USER) - Capabilities-safe verify (lane-policy →
readon data+metadata paths) - First read-only pull 2026-07-21 (122 txs); CostRunRate v2
(
finance/qonto-first-pull-2026-07-21.json) - Wire Finance Steward recurring session (post-cutover, harness lane — follow-on, out of scope for BINKY-WP-0005)
First-pull results (T05, 2026-07-21)
| Item | Value |
|---|---|
| Org | Binky Hedgehog GmbH |
| Main balance | 2 185,94 € |
| Desk (HUB31) | 297,50 €/mo |
| Qonto plan fee | 70,80 €/mo (since 2025-10; was 22,80 / 35,40 earlier) |
| Evidence | finance/qonto-first-pull-2026-07-21.json |
Harness read-only allow-list (enforce at session wire-up): organization, accounts, transactions, statements metadata, attachments metadata, labels. Never: cards, invoicing, payment requests, transfers.
Consumer fetch (after active)
bao login -method=oidc -path=netkingdom role=binky-qonto-api-workload-kv-read
umask 077
bao kv get -field=API_KEY tenants/binky/qonto-api > /tmp/qonto.key
bao kv get -field=API_USER tenants/binky/qonto-api > /tmp/qonto.user
export QONTO_API_KEY="$(cat /tmp/qonto.key)"
export QONTO_ORGANIZATION_ID="$(cat /tmp/qonto.user)"
shred -u /tmp/qonto.key /tmp/qonto.user
# Authorization for thirdparty API: "$QONTO_ORGANIZATION_ID:$QONTO_API_KEY"
See also
integrations/company-email-openbao.md— custody pattern being mirroredAutopilotWorkQueue.mdAWQ-010 (origin),OfficeHourQueue.mdOH-2026-003railiance-platformCCR-2026-0008 ·ops-wardencatalogbinky-qonto-api- Qonto docs: https://docs.qonto.com/mcp/overview, https://github.com/qonto/qonto-mcp-server