2026-07-19 14:26:55 +02:00
|
|
|
|
# Qonto MCP Integration — Design
|
|
|
|
|
|
|
2026-07-21 21:42:10 +02:00
|
|
|
|
> Status: **lane active** — 2026-07-21 (BINKY-WP-0005 finished).
|
2026-07-19 14:26:55 +02:00
|
|
|
|
> Goal: the company Qonto account becomes an agent-readable finance source
|
2026-07-21 21:42:10 +02:00
|
|
|
|
> (balance, transactions, statements) through the sanctioned harness/MCP /
|
|
|
|
|
|
> thirdparty API lane. **Read scopes first; payments/transfers are Red lane forever.**
|
|
|
|
|
|
> Credentials live at `tenants/binky/qonto-api` (CCR-2026-0008 / DEC-2026-004).
|
2026-07-19 14:26:55 +02:00
|
|
|
|
|
|
|
|
|
|
## 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` |
|
2026-07-21 21:42:10 +02:00
|
|
|
|
| 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) |
|
2026-07-19 14:26:55 +02:00
|
|
|
|
| Risk | high (full-scope bank API key — read-only is harness-enforced) |
|
|
|
|
|
|
|
2026-07-21 21:42:10 +02:00
|
|
|
|
Auth to Qonto thirdparty API: `Authorization: <API_USER>:<API_KEY>`.
|
|
|
|
|
|
|
2026-07-19 14:26:55 +02:00
|
|
|
|
```text
|
|
|
|
|
|
founder (Red lane, once)
|
2026-07-21 21:42:10 +02:00
|
|
|
|
└─ bao kv put tenants/binky/qonto-api API_KEY=@file API_USER=@file
|
|
|
|
|
|
└─ OpenBao: tenants/binky/qonto-api
|
2026-07-19 14:26:55 +02:00
|
|
|
|
└─ warden access binky-qonto-api --exec
|
2026-07-21 21:42:10 +02:00
|
|
|
|
└─ map fields → QONTO_* env → qonto-mcp-server / curl thirdparty
|
2026-07-19 14:26:55 +02:00
|
|
|
|
└─ finance/CostRunRate.md + rhythm session feeds
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Founder provision (Red lane — interactive human shell)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-21 21:42:10 +02:00
|
|
|
|
# In the Qonto dashboard: /settings/integrations → create API key, note login/org slug
|
2026-07-19 14:26:55 +02:00
|
|
|
|
umask 077
|
2026-07-21 21:42:10 +02:00
|
|
|
|
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
|
2026-07-19 14:26:55 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-21 21:42:10 +02:00
|
|
|
|
`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.**
|
2026-07-19 14:26:55 +02:00
|
|
|
|
|
|
|
|
|
|
## 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)
|
2026-07-21 21:42:10 +02:00
|
|
|
|
2. [x] OpenBao lane designed → **live path `tenants/binky/qonto-api`**
|
2026-07-19 14:26:55 +02:00
|
|
|
|
3. [x] DecisionQueue package prepared (DEC-2026-004)
|
2026-07-19 14:31:02 +02:00
|
|
|
|
4. [x] DEC-2026-004 **approved** (founder, 2026-07-19)
|
2026-07-21 21:42:10 +02:00
|
|
|
|
5. [x] CCR-2026-0008 **active** (policy + OIDC role + agent-high-risk-boundary)
|
|
|
|
|
|
6. [x] ops-warden catalog `binky-qonto-api` **active** + playbook
|
|
|
|
|
|
7. [x] Red-lane secret present (`API_KEY` + `API_USER`)
|
|
|
|
|
|
8. [x] Capabilities-safe verify (lane-policy → `read` on data+metadata paths)
|
|
|
|
|
|
9. [x] First read-only pull 2026-07-21 (122 txs); CostRunRate v2
|
|
|
|
|
|
(`finance/qonto-first-pull-2026-07-21.json`)
|
|
|
|
|
|
10. [ ] Wire Finance Steward recurring session (post-cutover, harness lane —
|
|
|
|
|
|
**follow-on**, out of scope for BINKY-WP-0005)
|
2026-07-21 21:26:25 +02:00
|
|
|
|
|
2026-07-21 21:42:10 +02:00
|
|
|
|
## First-pull results (T05, 2026-07-21)
|
2026-07-21 21:26:25 +02:00
|
|
|
|
|
2026-07-21 21:42:10 +02:00
|
|
|
|
| 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` |
|
2026-07-21 21:26:25 +02:00
|
|
|
|
|
2026-07-21 21:42:10 +02:00
|
|
|
|
**Harness read-only allow-list (enforce at session wire-up):** organization,
|
|
|
|
|
|
accounts, transactions, statements metadata, attachments metadata, labels.
|
|
|
|
|
|
Never: cards, invoicing, payment requests, transfers.
|
2026-07-21 21:26:25 +02:00
|
|
|
|
|
2026-07-21 21:42:10 +02:00
|
|
|
|
### Consumer fetch (after active)
|
2026-07-21 21:26:25 +02:00
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-21 21:42:10 +02:00
|
|
|
|
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"
|
2026-07-21 21:26:25 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-19 14:26:55 +02:00
|
|
|
|
## See also
|
|
|
|
|
|
|
|
|
|
|
|
- `integrations/company-email-openbao.md` — custody pattern being mirrored
|
|
|
|
|
|
- `AutopilotWorkQueue.md` AWQ-010 (origin), `OfficeHourQueue.md` OH-2026-003
|
2026-07-21 21:26:25 +02:00
|
|
|
|
- `railiance-platform` CCR-2026-0008 · `ops-warden` catalog `binky-qonto-api`
|
2026-07-19 14:26:55 +02:00
|
|
|
|
- Qonto docs: <https://docs.qonto.com/mcp/overview>,
|
|
|
|
|
|
<https://github.com/qonto/qonto-mcp-server>
|