From ce2db72f7cf698c676497baf42555b6f865c2b54 Mon Sep 17 00:00:00 2001
From: GallaGit <230304929+GallaGit@users.noreply.github.com>
Date: Tue, 13 Oct 2026 16:40:42 +0200
Subject: [PATCH 1/3] feat(adapters): add read-only Qonto business banking
adapter (#1013)
Adds fr/qonto.json with 7 GET tools against the Qonto Business API v2
(login:secret-key Authorization header), a static + RUN_QONTO_LIVE=1
sandbox spec, the Qonto logo, regenerated catalog and bumped counts.
Closes #1013
---
CITATION.cff | 2 +-
README.de.md | 6 +-
README.ja.md | 6 +-
README.md | 6 +-
README.zh-CN.md | 6 +-
glama.json | 2 +-
package.json | 2 +-
packages/backend/src/adapters/catalog.ts | 2 +
packages/backend/src/adapters/fr/qonto.json | 339 ++++++++++++++++++
.../src/adapters/fr/qonto.live.spec.ts | 90 +++++
.../public/logos/connectors/qonto.svg | 8 +
server.json | 2 +-
12 files changed, 455 insertions(+), 16 deletions(-)
create mode 100644 packages/backend/src/adapters/fr/qonto.json
create mode 100644 packages/backend/src/adapters/fr/qonto.live.spec.ts
create mode 100644 packages/frontend/public/logos/connectors/qonto.svg
diff --git a/CITATION.cff b/CITATION.cff
index 374b0800f..903622e2b 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -13,7 +13,7 @@ abstract: >
server that turns REST/OpenAPI, SOAP/WSDL and GraphQL APIs, SQL/NoSQL
databases and other MCP servers into tools for AI clients such as Claude,
ChatGPT, Google Gemini, GitHub Copilot and Cursor, without writing code.
- It ships 385 pre-built adapters, with a focus on ERP and e-commerce
+ It ships 386 pre-built adapters, with a focus on ERP and e-commerce
systems (SAP Business One, Odoo, Xentral, JTL-Wawi, weclapp, Shopware,
WooCommerce, Amazon Seller, Kaufland, OTTO, etc.), a per-workspace
knowledge graph served over MCP, per-tool response mapping,
diff --git a/README.de.md b/README.de.md
index e8dfd34c4..79d8216a9 100644
--- a/README.de.md
+++ b/README.de.md
@@ -1,5 +1,5 @@
-
+
AnythingMCP: selbst gehostetes MCP-Gateway
@@ -19,7 +19,7 @@
AnythingMCP ist ein quelloffenes, selbst gehostetes MCP-Gateway, das jedes REST-/OpenAPI-, SOAP-, GraphQL-, OData- oder SQL-System in MCP-Tools für Claude, ChatGPT und Copilot verwandelt, ohne dass du einen MCP-Server programmierst.
- Es bringt 385 fertige Adapter mit, darunter SAP, Etsy, weclapp und Amazon Seller; 19 davon kommen ohne API-Schlüssel aus.
+ Es bringt 386 fertige Adapter mit, darunter SAP, Etsy, weclapp und Amazon Seller; 19 davon kommen ohne API-Schlüssel aus.
@@ -111,7 +111,7 @@ Tools werden zur Laufzeit registriert, ohne Neustart. `{{VAR}}`-Werte pro Connec
## Connector-Katalog
-385 Adapter mit über 2.400 Tools. Zu jedem gibt es eine Einrichtungsanleitung auf [anythingmcp.com/de/guides](https://anythingmcp.com/de/guides), in sieben Sprachen.
+386 Adapter mit über 2.400 Tools. Zu jedem gibt es eine Einrichtungsanleitung auf [anythingmcp.com/de/guides](https://anythingmcp.com/de/guides), in sieben Sprachen.
| Kategorie | Beispiele |
|---|---|
diff --git a/README.ja.md b/README.ja.md
index 160126d55..7f859c881 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -1,5 +1,5 @@
AnythingMCP is an open-source, self-hosted MCP gateway that turns any REST/OpenAPI, SOAP, GraphQL, OData or SQL system into MCP tools for Claude, ChatGPT and Copilot, without writing an MCP server.
- It ships 385 ready connectors, among them SAP, Etsy, weclapp and Amazon Seller, and 19 of them need no API key.
+ It ships 386 ready connectors, among them SAP, Etsy, weclapp and Amazon Seller, and 19 of them need no API key.
@@ -103,7 +103,7 @@ Tools register at runtime, without a restart. Per-connector `{{VAR}}` values are
## Connector catalog
-385 adapters, exposing 2,400+ tools. Every one has a setup guide on [anythingmcp.com/guides](https://anythingmcp.com/guides), in seven languages.
+386 adapters, exposing 2,400+ tools. Every one has a setup guide on [anythingmcp.com/guides](https://anythingmcp.com/guides), in seven languages.
| Category | Examples |
|---|---|
diff --git a/README.zh-CN.md b/README.zh-CN.md
index ef1e7f4d7..02199444c 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -1,5 +1,5 @@
@@ -111,7 +111,7 @@ docker compose up -d
## 连接器目录
-共 385 个适配器,提供 2,400 多个工具。每个适配器都在 [anythingmcp.com/zh/guides](https://anythingmcp.com/zh/guides) 上提供七种语言的配置指南。
+共 386 个适配器,提供 2,400 多个工具。每个适配器都在 [anythingmcp.com/zh/guides](https://anythingmcp.com/zh/guides) 上提供七种语言的配置指南。
| 类别 | 示例 |
|---|---|
diff --git a/glama.json b/glama.json
index 2182a599e..f97a21102 100644
--- a/glama.json
+++ b/glama.json
@@ -3,5 +3,5 @@
"maintainers": [
"helpcodeai"
],
- "description": "Turn any REST/OpenAPI, SOAP/WSDL, GraphQL, OData or SQL API into MCP tools for Claude, ChatGPT and Copilot, no code. 385 pre-built adapters for ERP and e-commerce (SAP S/4HANA, SAP Business One, Odoo, Xentral, JTL-Wawi, weclapp, Shopware, WooCommerce, Amazon Seller, Kaufland, OTTO\u2026) and more. Self-hosted, knowledge graph, per-tool response mapping, OAuth2/RBAC/SSO/audit. Open source under AGPL-3.0."
+ "description": "Turn any REST/OpenAPI, SOAP/WSDL, GraphQL, OData or SQL API into MCP tools for Claude, ChatGPT and Copilot, no code. 386 pre-built adapters for ERP and e-commerce (SAP S/4HANA, SAP Business One, Odoo, Xentral, JTL-Wawi, weclapp, Shopware, WooCommerce, Amazon Seller, Kaufland, OTTO\u2026) and more. Self-hosted, knowledge graph, per-tool response mapping, OAuth2/RBAC/SSO/audit. Open source under AGPL-3.0."
}
diff --git a/package.json b/package.json
index c1c3d4614..5c3e99bd6 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "anythingmcp",
"version": "0.28.0",
- "description": "Turn any REST/OpenAPI, SOAP/WSDL, GraphQL, OData or SQL API into MCP tools for Claude, ChatGPT and Copilot, no code. 385 pre-built adapters for ERP, e-commerce and more (SAP S/4HANA, SAP Business One, Odoo, Xentral, JTL-Wawi, Shopware, WooCommerce, Amazon Seller). Self-hosted, open source (AGPL-3.0).",
+ "description": "Turn any REST/OpenAPI, SOAP/WSDL, GraphQL, OData or SQL API into MCP tools for Claude, ChatGPT and Copilot, no code. 386 pre-built adapters for ERP, e-commerce and more (SAP S/4HANA, SAP Business One, Odoo, Xentral, JTL-Wawi, Shopware, WooCommerce, Amazon Seller). Self-hosted, open source (AGPL-3.0).",
"private": true,
"license": "AGPL-3.0-only",
"engines": {
diff --git a/packages/backend/src/adapters/catalog.ts b/packages/backend/src/adapters/catalog.ts
index 993b84de2..fc45ab1a8 100644
--- a/packages/backend/src/adapters/catalog.ts
+++ b/packages/backend/src/adapters/catalog.ts
@@ -383,6 +383,7 @@ import * as quipu from './es/quipu.json';
import * as axonaut from './fr/axonaut.json';
import * as dolibarr from './fr/dolibarr.json';
import * as pennylane from './fr/pennylane.json';
+import * as qonto from './fr/qonto.json';
import * as sellsy from './fr/sellsy.json';
import * as afasProfit from './nl/afas-profit.json';
import * as exactOnline from './nl/exact-online.json';
@@ -984,6 +985,7 @@ const RAW_ADAPTERS: AdapterDefinition[] = [
axonaut as unknown as AdapterDefinition,
dolibarr as unknown as AdapterDefinition,
pennylane as unknown as AdapterDefinition,
+ qonto as unknown as AdapterDefinition,
sellsy as unknown as AdapterDefinition,
afasProfit as unknown as AdapterDefinition,
exactOnline as unknown as AdapterDefinition,
diff --git a/packages/backend/src/adapters/fr/qonto.json b/packages/backend/src/adapters/fr/qonto.json
new file mode 100644
index 000000000..14901a4eb
--- /dev/null
+++ b/packages/backend/src/adapters/fr/qonto.json
@@ -0,0 +1,339 @@
+{
+ "slug": "qonto",
+ "name": "Qonto",
+ "description": "Qonto — French business account for SMBs and freelancers: organization and bank accounts, transactions, client and supplier invoices, clients and quotes. Official Business API v2, read-only, login:secret-key API key. 7 tools.",
+ "instructions": "This connector reads your **Qonto** business account through the official Business API: organization and bank accounts, transactions, client invoices, supplier invoices, clients and quotes. It is **read-only**: every tool is a GET, so it cannot send transfers, add beneficiaries, touch cards or create, edit or delete invoices.\n\n**Getting the credentials**\n1. Sign in to the Qonto web app (https://app.qonto.com) and, if you have several organizations, pick the one to connect.\n2. Open **Integrations & Partnerships → API key** and click **Generate** if no secret key exists yet.\n3. Put the **login** (sign-in, e.g. `pied-piper-7132`) in `QONTO_LOGIN` and the **secret key** in `QONTO_SECRET_KEY`.\n\n**How authentication works**: Qonto expects `Authorization: :`. This looks like HTTP Basic but is not: no Base64 and no `Bearer` prefix. A 401 almost always means a wrong login or secret.\n\n**Bank data is sensitive.** The connector sees every bank account of the organization. Assign it only to MCP servers whose users are allowed to see the company's bank accounts and transactions.\n\n**Workflow**: call `qonto_get_organization` first to get the bank account `id` (or IBAN); `qonto_list_transactions` works on one account at a time and needs one of them.\n\n**Pagination**: list tools take `page` and `per_page` (1 to 100, default 100); responses carry `meta.next_page` and `meta.total_pages`.\n\n**Amounts**: transactions expose `amount` and `amount_cents`; prefer the cents for arithmetic.\n\n**Sandbox**: create an application on the Qonto Developer Portal (https://developers.qonto.com) to get a sandbox organization and a personal staging token. After install, edit the connector: set the base URL to `https://thirdparty-sandbox.staging.qonto.co/v2` and add the header `X-Qonto-Staging-Token: ` (case-sensitive). Without it, sandbox calls return a OneLogin HTML page instead of JSON. The staging token is not accepted in production.\n\n**Cloud reachability**: thirdparty.qonto.com is public with a valid certificate.",
+ "region": "fr",
+ "category": "banking",
+ "icon": "qonto",
+ "docsUrl": "https://docs.qonto.com/",
+ "requiredEnvVars": [
+ "QONTO_LOGIN",
+ "QONTO_SECRET_KEY"
+ ],
+ "probe": {
+ "tool": "qonto_get_organization"
+ },
+ "connector": {
+ "name": "Qonto Business API v2",
+ "type": "REST",
+ "baseUrl": "https://thirdparty.qonto.com/v2",
+ "authType": "API_KEY",
+ "authConfig": {
+ "headerName": "Authorization",
+ "apiKey": "{{QONTO_LOGIN}}:{{QONTO_SECRET_KEY}}"
+ },
+ "headers": {
+ "Accept": "application/json"
+ }
+ },
+ "tools": [
+ {
+ "name": "qonto_get_organization",
+ "description": "Get the Qonto organization: legal name, slug and every bank account with its id, IBAN, BIC, currency, balance and status. Call this first: qonto_list_transactions needs a bank account id or IBAN from here.",
+ "parameters": {
+ "type": "object",
+ "properties": {}
+ },
+ "endpointMapping": {
+ "method": "GET",
+ "path": "/organization"
+ }
+ },
+ {
+ "name": "qonto_list_transactions",
+ "description": "List transactions of ONE bank account. Requires bank_account_id or iban taken from qonto_get_organization first. Filter by settled/emitted date range, side (credit/debit), status and operation type; paginated with page/per_page.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "bank_account_id": {
+ "type": "string",
+ "description": "Bank account id from qonto_get_organization. Takes precedence over iban when both are set."
+ },
+ "iban": {
+ "type": "string",
+ "description": "IBAN of the bank account, from qonto_get_organization."
+ },
+ "settled_at_from": {
+ "type": "string",
+ "description": "ISO 8601 timestamp; only transactions settled at or after it."
+ },
+ "settled_at_to": {
+ "type": "string",
+ "description": "ISO 8601 timestamp; only transactions settled at or before it."
+ },
+ "emitted_at_from": {
+ "type": "string",
+ "description": "ISO 8601 timestamp; only transactions emitted at or after it."
+ },
+ "emitted_at_to": {
+ "type": "string",
+ "description": "ISO 8601 timestamp; only transactions emitted at or before it."
+ },
+ "side": {
+ "type": "string",
+ "description": "credit (money in) or debit (money out)."
+ },
+ "status": {
+ "type": "string",
+ "description": "Transaction status, e.g. pending, declined, completed (sent as status[])."
+ },
+ "operation_type": {
+ "type": "string",
+ "description": "Operation type, e.g. card, transfer, direct_debit, income (sent as operation_type[])."
+ },
+ "with_attachments": {
+ "type": "boolean",
+ "description": "true to keep only transactions with attachments, false for those without."
+ },
+ "sort_by": {
+ "type": "string",
+ "description": "Sort order, e.g. settled_at:desc."
+ },
+ "page": {
+ "type": "integer",
+ "description": "Page number, starting at 1 (Qonto default 1)."
+ },
+ "per_page": {
+ "type": "integer",
+ "description": "Items per page, 1 to 100 (Qonto default 100)."
+ }
+ }
+ },
+ "endpointMapping": {
+ "method": "GET",
+ "path": "/transactions",
+ "queryParams": {
+ "bank_account_id": "$bank_account_id",
+ "iban": "$iban",
+ "settled_at_from": "$settled_at_from",
+ "settled_at_to": "$settled_at_to",
+ "emitted_at_from": "$emitted_at_from",
+ "emitted_at_to": "$emitted_at_to",
+ "side": "$side",
+ "status[]": "$status",
+ "operation_type[]": "$operation_type",
+ "with_attachments": "$with_attachments",
+ "sort_by": "$sort_by",
+ "page": "$page",
+ "per_page": "$per_page"
+ }
+ }
+ },
+ {
+ "name": "qonto_get_transaction",
+ "description": "Get one transaction by its id: amount, currency, side, counterparty, label, status, operation type, dates, category and attachment ids. Use ids returned by qonto_list_transactions.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Transaction id (UUID) from qonto_list_transactions."
+ }
+ },
+ "required": [
+ "id"
+ ]
+ },
+ "endpointMapping": {
+ "method": "GET",
+ "path": "/transactions/{id}"
+ }
+ },
+ {
+ "name": "qonto_list_client_invoices",
+ "description": "List the client invoices the organization issued from Qonto, filtered by status and by due date, creation or update date ranges. Answers questions like unpaid invoices due this week.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "description": "Invoice status, e.g. draft, unpaid, paid, canceled (filter[status])."
+ },
+ "due_date_from": {
+ "type": "string",
+ "description": "Date YYYY-MM-DD; due on or after (filter[due_date_from])."
+ },
+ "due_date_to": {
+ "type": "string",
+ "description": "Date YYYY-MM-DD; due on or before (filter[due_date_to])."
+ },
+ "created_at_from": {
+ "type": "string",
+ "description": "ISO 8601; created on or after (filter[created_at_from])."
+ },
+ "created_at_to": {
+ "type": "string",
+ "description": "ISO 8601; created on or before (filter[created_at_to])."
+ },
+ "sort_by": {
+ "type": "string",
+ "description": "Sort order, e.g. created_at:desc."
+ },
+ "page": {
+ "type": "integer",
+ "description": "Page number, starting at 1 (Qonto default 1)."
+ },
+ "per_page": {
+ "type": "integer",
+ "description": "Items per page, 1 to 100 (Qonto default 100)."
+ }
+ }
+ },
+ "endpointMapping": {
+ "method": "GET",
+ "path": "/client_invoices",
+ "queryParams": {
+ "filter[status]": "$status",
+ "filter[due_date_from]": "$due_date_from",
+ "filter[due_date_to]": "$due_date_to",
+ "filter[created_at_from]": "$created_at_from",
+ "filter[created_at_to]": "$created_at_to",
+ "sort_by": "$sort_by",
+ "page": "$page",
+ "per_page": "$per_page"
+ }
+ }
+ },
+ {
+ "name": "qonto_list_supplier_invoices",
+ "description": "List supplier invoices received in Qonto, filtered by status, creation date and a free-text query (supplier name, invoice number). Useful to find bills to pay or missing documents.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "description": "Supplier invoice status, e.g. to_review, to_pay, paid (filter[status])."
+ },
+ "created_at_from": {
+ "type": "string",
+ "description": "ISO 8601; created on or after (filter[created_at_from])."
+ },
+ "created_at_to": {
+ "type": "string",
+ "description": "ISO 8601; created on or before (filter[created_at_to])."
+ },
+ "query": {
+ "type": "string",
+ "description": "Free-text search over supplier name, invoice number and similar fields."
+ },
+ "sort_by": {
+ "type": "string",
+ "description": "Sort order, e.g. created_at:desc."
+ },
+ "page": {
+ "type": "integer",
+ "description": "Page number, starting at 1 (Qonto default 1)."
+ },
+ "per_page": {
+ "type": "integer",
+ "description": "Items per page, 1 to 100 (Qonto default 100)."
+ }
+ }
+ },
+ "endpointMapping": {
+ "method": "GET",
+ "path": "/supplier_invoices",
+ "queryParams": {
+ "filter[status]": "$status",
+ "filter[created_at_from]": "$created_at_from",
+ "filter[created_at_to]": "$created_at_to",
+ "query": "$query",
+ "sort_by": "$sort_by",
+ "page": "$page",
+ "per_page": "$per_page"
+ }
+ }
+ },
+ {
+ "name": "qonto_list_clients",
+ "description": "List the clients (customers) in the Qonto invoicing address book, optionally filtered by name, VAT number or email. Returns ids, contact data and billing addresses.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Filter by client name (filter[name])."
+ },
+ "vat_number": {
+ "type": "string",
+ "description": "Filter by VAT number (filter[vat_number])."
+ },
+ "email": {
+ "type": "string",
+ "description": "Filter by email (filter[email])."
+ },
+ "sort_by": {
+ "type": "string",
+ "description": "Sort order, e.g. name:asc."
+ },
+ "page": {
+ "type": "integer",
+ "description": "Page number, starting at 1 (Qonto default 1)."
+ },
+ "per_page": {
+ "type": "integer",
+ "description": "Items per page, 1 to 100 (Qonto default 100)."
+ }
+ }
+ },
+ "endpointMapping": {
+ "method": "GET",
+ "path": "/clients",
+ "queryParams": {
+ "filter[name]": "$name",
+ "filter[vat_number]": "$vat_number",
+ "filter[email]": "$email",
+ "sort_by": "$sort_by",
+ "page": "$page",
+ "per_page": "$per_page"
+ }
+ }
+ },
+ {
+ "name": "qonto_list_quotes",
+ "description": "List the quotes (devis) created in Qonto, filtered by status and creation date range, with client, amounts, validity and status. Read-only: it cannot create or send quotes.",
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "status": {
+ "type": "string",
+ "description": "Quote status, e.g. pending_approval, approved, canceled (filter[status])."
+ },
+ "created_at_from": {
+ "type": "string",
+ "description": "ISO 8601; created on or after (filter[created_at_from])."
+ },
+ "created_at_to": {
+ "type": "string",
+ "description": "ISO 8601; created on or before (filter[created_at_to])."
+ },
+ "sort_by": {
+ "type": "string",
+ "description": "Sort order, e.g. created_at:desc."
+ },
+ "page": {
+ "type": "integer",
+ "description": "Page number, starting at 1 (Qonto default 1)."
+ },
+ "per_page": {
+ "type": "integer",
+ "description": "Items per page, 1 to 100 (Qonto default 100)."
+ }
+ }
+ },
+ "endpointMapping": {
+ "method": "GET",
+ "path": "/quotes",
+ "queryParams": {
+ "filter[status]": "$status",
+ "filter[created_at_from]": "$created_at_from",
+ "filter[created_at_to]": "$created_at_to",
+ "sort_by": "$sort_by",
+ "page": "$page",
+ "per_page": "$per_page"
+ }
+ }
+ }
+ ]
+}
diff --git a/packages/backend/src/adapters/fr/qonto.live.spec.ts b/packages/backend/src/adapters/fr/qonto.live.spec.ts
new file mode 100644
index 000000000..e4e175234
--- /dev/null
+++ b/packages/backend/src/adapters/fr/qonto.live.spec.ts
@@ -0,0 +1,90 @@
+import * as adapter from './qonto.json';
+
+const a = adapter as unknown as {
+ category: string;
+ requiredEnvVars: string[];
+ instructions: string;
+ probe: { tool: string };
+ connector: { baseUrl: string; authType: string; authConfig: Record };
+ tools: Array<{ name: string; description: string; endpointMapping: { method: string; path: string } }>;
+};
+
+// Values from docs.qonto.com: "API key" authentication page, "Pagination",
+// "Accessing the Sandbox environment" and the Business API v2 reference.
+describe('qonto adapter — static spec conformance', () => {
+ it('calls the production Business API v2', () =>
+ expect(a.connector.baseUrl).toBe('https://thirdparty.qonto.com/v2'));
+
+ it('sends login:secret-key in Authorization, no Bearer, no Base64', () => {
+ expect(a.connector.authType).toBe('API_KEY');
+ expect(a.connector.authConfig.headerName).toBe('Authorization');
+ expect(a.connector.authConfig.apiKey).toBe('{{QONTO_LOGIN}}:{{QONTO_SECRET_KEY}}');
+ expect(a.connector.authConfig.apiKey).toContain(':');
+ expect(a.connector.authConfig.apiKey).not.toMatch(/bearer|basic/i);
+ expect(a.requiredEnvVars).toEqual(['QONTO_LOGIN', 'QONTO_SECRET_KEY']);
+ });
+
+ it('only reads: every tool is a GET', () => {
+ for (const tool of a.tools) {
+ expect(['POST', 'PUT', 'PATCH', 'DELETE']).not.toContain(tool.endpointMapping.method);
+ expect(tool.endpointMapping.method).toBe('GET');
+ }
+ });
+
+ it('uses the documented endpoint paths', () => {
+ expect(Object.fromEntries(a.tools.map((t) => [t.name, t.endpointMapping.path]))).toEqual({
+ qonto_get_organization: '/organization',
+ qonto_list_transactions: '/transactions',
+ qonto_get_transaction: '/transactions/{id}',
+ qonto_list_client_invoices: '/client_invoices',
+ qonto_list_supplier_invoices: '/supplier_invoices',
+ qonto_list_clients: '/clients',
+ qonto_list_quotes: '/quotes',
+ });
+ });
+
+ it('is a banking adapter probed with the organization', () => {
+ expect(a.category).toBe('banking');
+ expect(a.probe.tool).toBe('qonto_get_organization');
+ });
+
+ it('tells the agent to fetch a bank account before listing transactions', () => {
+ const tx = a.tools.find((t) => t.name === 'qonto_list_transactions')!;
+ expect(tx.description).toContain('qonto_get_organization');
+ });
+
+ it('documents the sandbox host and staging header', () => {
+ expect(a.instructions).toContain('https://thirdparty-sandbox.staging.qonto.co/v2');
+ expect(a.instructions).toContain('X-Qonto-Staging-Token');
+ });
+});
+
+// Opt-in live check against the Qonto sandbox. Needs QONTO_LOGIN,
+// QONTO_SECRET_KEY and QONTO_STAGING_TOKEN; QONTO_BASE_URL overrides the host.
+const live = process.env.RUN_QONTO_LIVE === '1';
+(live ? describe : describe.skip)('qonto — live (sandbox)', () => {
+ const base = process.env.QONTO_BASE_URL ?? 'https://thirdparty-sandbox.staging.qonto.co/v2';
+ const headers: Record = {
+ Authorization: `${process.env.QONTO_LOGIN}:${process.env.QONTO_SECRET_KEY}`,
+ Accept: 'application/json',
+ };
+ if (process.env.QONTO_STAGING_TOKEN) headers['X-Qonto-Staging-Token'] = process.env.QONTO_STAGING_TOKEN;
+
+ let accountId: string | undefined;
+
+ it('reads the organization and its bank accounts', async () => {
+ const res = await fetch(`${base}/organization`, { headers });
+ expect(res.status).toBe(200);
+ const body = (await res.json()) as { organization: { bank_accounts: Array<{ id: string }> } };
+ accountId = body.organization.bank_accounts[0]?.id;
+ expect(accountId).toBeTruthy();
+ });
+
+ it('lists transactions of the first bank account', async () => {
+ const res = await fetch(`${base}/transactions?bank_account_id=${accountId}&per_page=5`, { headers });
+ expect(res.status).toBe(200);
+ const body = (await res.json()) as { transactions: unknown[]; meta: { current_page: number } };
+ expect(Array.isArray(body.transactions)).toBe(true);
+ expect(body.meta.current_page).toBe(1);
+ });
+});
diff --git a/packages/frontend/public/logos/connectors/qonto.svg b/packages/frontend/public/logos/connectors/qonto.svg
new file mode 100644
index 000000000..c12a668ec
--- /dev/null
+++ b/packages/frontend/public/logos/connectors/qonto.svg
@@ -0,0 +1,8 @@
+
diff --git a/server.json b/server.json
index 33ecf0ec1..bfe893eb2 100644
--- a/server.json
+++ b/server.json
@@ -2,7 +2,7 @@
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.HelpCode-ai/anythingmcp",
"title": "AnythingMCP",
- "description": "Any REST/SOAP/GraphQL/OData/SQL API as MCP tools for Claude & ChatGPT. 385 connectors: SAP, ERP.",
+ "description": "Any REST/SOAP/GraphQL/OData/SQL API as MCP tools for Claude & ChatGPT. 386 connectors: SAP, ERP.",
"repository": {
"url": "https://github.com/HelpCode-ai/anythingmcp",
"source": "github"
From 2994eea557f2ce305a6093ea4e629bb66da09501 Mon Sep 17 00:00:00 2001
From: GallaGit <230304929+GallaGit@users.noreply.github.com>
Date: Tue, 13 Oct 2026 16:57:25 +0200
Subject: [PATCH 2/3] fix(adapters): refine Qonto tool docs and filters after
review (#1013)
- soften bank_account_id/iban wording (recommended, pending verification)
- transactions: document completed-only default, add reversed, one status per call
- client invoices: add filter[updated_at_from/to]
- supplier invoices: use to_review instead of deprecated to_pay, expose query_fields
---
packages/backend/src/adapters/fr/qonto.json | 27 ++++++++++++++-----
.../src/adapters/fr/qonto.live.spec.ts | 7 +++++
2 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/packages/backend/src/adapters/fr/qonto.json b/packages/backend/src/adapters/fr/qonto.json
index 14901a4eb..9527d8f40 100644
--- a/packages/backend/src/adapters/fr/qonto.json
+++ b/packages/backend/src/adapters/fr/qonto.json
@@ -2,7 +2,7 @@
"slug": "qonto",
"name": "Qonto",
"description": "Qonto — French business account for SMBs and freelancers: organization and bank accounts, transactions, client and supplier invoices, clients and quotes. Official Business API v2, read-only, login:secret-key API key. 7 tools.",
- "instructions": "This connector reads your **Qonto** business account through the official Business API: organization and bank accounts, transactions, client invoices, supplier invoices, clients and quotes. It is **read-only**: every tool is a GET, so it cannot send transfers, add beneficiaries, touch cards or create, edit or delete invoices.\n\n**Getting the credentials**\n1. Sign in to the Qonto web app (https://app.qonto.com) and, if you have several organizations, pick the one to connect.\n2. Open **Integrations & Partnerships → API key** and click **Generate** if no secret key exists yet.\n3. Put the **login** (sign-in, e.g. `pied-piper-7132`) in `QONTO_LOGIN` and the **secret key** in `QONTO_SECRET_KEY`.\n\n**How authentication works**: Qonto expects `Authorization: :`. This looks like HTTP Basic but is not: no Base64 and no `Bearer` prefix. A 401 almost always means a wrong login or secret.\n\n**Bank data is sensitive.** The connector sees every bank account of the organization. Assign it only to MCP servers whose users are allowed to see the company's bank accounts and transactions.\n\n**Workflow**: call `qonto_get_organization` first to get the bank account `id` (or IBAN); `qonto_list_transactions` works on one account at a time and needs one of them.\n\n**Pagination**: list tools take `page` and `per_page` (1 to 100, default 100); responses carry `meta.next_page` and `meta.total_pages`.\n\n**Amounts**: transactions expose `amount` and `amount_cents`; prefer the cents for arithmetic.\n\n**Sandbox**: create an application on the Qonto Developer Portal (https://developers.qonto.com) to get a sandbox organization and a personal staging token. After install, edit the connector: set the base URL to `https://thirdparty-sandbox.staging.qonto.co/v2` and add the header `X-Qonto-Staging-Token: ` (case-sensitive). Without it, sandbox calls return a OneLogin HTML page instead of JSON. The staging token is not accepted in production.\n\n**Cloud reachability**: thirdparty.qonto.com is public with a valid certificate.",
+ "instructions": "This connector reads your **Qonto** business account through the official Business API: organization and bank accounts, transactions, client invoices, supplier invoices, clients and quotes. It is **read-only**: every tool is a GET, so it cannot send transfers, add beneficiaries, touch cards or create, edit or delete invoices.\n\n**Getting the credentials**\n1. Sign in to the Qonto web app (https://app.qonto.com) and, if you have several organizations, pick the one to connect.\n2. Open **Integrations & Partnerships → API key** and click **Generate** if no secret key exists yet.\n3. Put the **login** (sign-in, e.g. `pied-piper-7132`) in `QONTO_LOGIN` and the **secret key** in `QONTO_SECRET_KEY`.\n\n**How authentication works**: Qonto expects `Authorization: :`. This looks like HTTP Basic but is not: no Base64 and no `Bearer` prefix. A 401 almost always means a wrong login or secret.\n\n**Bank data is sensitive.** The connector sees every bank account of the organization. Assign it only to MCP servers whose users are allowed to see the company's bank accounts and transactions.\n\n**Workflow**: call `qonto_get_organization` first to get the bank account `id` (or IBAN); `qonto_list_transactions` lists one account at a time; passing `bank_account_id` or `iban` is recommended (whether Qonto rejects a call without them is pending verification).\n\n**Pagination**: list tools take `page` and `per_page` (1 to 100, default 100); responses carry `meta.next_page` and `meta.total_pages`.\n\n**Amounts**: transactions expose `amount` and `amount_cents`; prefer the cents for arithmetic.\n\n**Sandbox**: create an application on the Qonto Developer Portal (https://developers.qonto.com) to get a sandbox organization and a personal staging token. After install, edit the connector: set the base URL to `https://thirdparty-sandbox.staging.qonto.co/v2` and add the header `X-Qonto-Staging-Token: ` (case-sensitive). Without it, sandbox calls return a OneLogin HTML page instead of JSON. The staging token is not accepted in production.\n\n**Cloud reachability**: thirdparty.qonto.com is public with a valid certificate.",
"region": "fr",
"category": "banking",
"icon": "qonto",
@@ -42,7 +42,7 @@
},
{
"name": "qonto_list_transactions",
- "description": "List transactions of ONE bank account. Requires bank_account_id or iban taken from qonto_get_organization first. Filter by settled/emitted date range, side (credit/debit), status and operation type; paginated with page/per_page.",
+ "description": "List transactions of one bank account. Pass bank_account_id or iban (recommended; call qonto_get_organization first to get them, a call without them is pending verification). Without a status filter Qonto returns only completed transactions. Filter by date range, side, status and operation type; paginated.",
"parameters": {
"type": "object",
"properties": {
@@ -76,7 +76,7 @@
},
"status": {
"type": "string",
- "description": "Transaction status, e.g. pending, declined, completed (sent as status[])."
+ "description": "One status per call: pending, declined, completed or reversed (sent as status[]). When omitted, Qonto returns only completed transactions, so set it to see pending or declined ones."
},
"operation_type": {
"type": "string",
@@ -177,6 +177,14 @@
"per_page": {
"type": "integer",
"description": "Items per page, 1 to 100 (Qonto default 100)."
+ },
+ "updated_at_from": {
+ "type": "string",
+ "description": "ISO 8601; updated on or after (filter[updated_at_from])."
+ },
+ "updated_at_to": {
+ "type": "string",
+ "description": "ISO 8601; updated on or before (filter[updated_at_to])."
}
}
},
@@ -189,6 +197,8 @@
"filter[due_date_to]": "$due_date_to",
"filter[created_at_from]": "$created_at_from",
"filter[created_at_to]": "$created_at_to",
+ "filter[updated_at_from]": "$updated_at_from",
+ "filter[updated_at_to]": "$updated_at_to",
"sort_by": "$sort_by",
"page": "$page",
"per_page": "$per_page"
@@ -197,13 +207,13 @@
},
{
"name": "qonto_list_supplier_invoices",
- "description": "List supplier invoices received in Qonto, filtered by status, creation date and a free-text query (supplier name, invoice number). Useful to find bills to pay or missing documents.",
+ "description": "List supplier invoices received in Qonto, filtered by status, creation date and a free-text query over the fields named in query_fields. Useful to find bills to review or pay, or missing documents.",
"parameters": {
"type": "object",
"properties": {
"status": {
"type": "string",
- "description": "Supplier invoice status, e.g. to_review, to_pay, paid (filter[status])."
+ "description": "Supplier invoice status, e.g. to_review, to_approve, awaiting_payment, pending, paid (filter[status]). to_pay is deprecated by Qonto; use to_review."
},
"created_at_from": {
"type": "string",
@@ -215,7 +225,11 @@
},
"query": {
"type": "string",
- "description": "Free-text search over supplier name, invoice number and similar fields."
+ "description": "Free-text search; Qonto applies it to the fields listed in query_fields."
+ },
+ "query_fields": {
+ "type": "string",
+ "description": "Comma-separated fields searched by query, e.g. supplier_name,amount,file_name,invoice_number."
},
"sort_by": {
"type": "string",
@@ -239,6 +253,7 @@
"filter[created_at_from]": "$created_at_from",
"filter[created_at_to]": "$created_at_to",
"query": "$query",
+ "query_fields": "$query_fields",
"sort_by": "$sort_by",
"page": "$page",
"per_page": "$per_page"
diff --git a/packages/backend/src/adapters/fr/qonto.live.spec.ts b/packages/backend/src/adapters/fr/qonto.live.spec.ts
index e4e175234..d762caa56 100644
--- a/packages/backend/src/adapters/fr/qonto.live.spec.ts
+++ b/packages/backend/src/adapters/fr/qonto.live.spec.ts
@@ -51,6 +51,13 @@ describe('qonto adapter — static spec conformance', () => {
it('tells the agent to fetch a bank account before listing transactions', () => {
const tx = a.tools.find((t) => t.name === 'qonto_list_transactions')!;
expect(tx.description).toContain('qonto_get_organization');
+ expect(tx.description).toContain('only completed');
+ });
+
+ it('does not suggest the deprecated to_pay supplier invoice status as a filter', () => {
+ const si = a.tools.find((t) => t.name === 'qonto_list_supplier_invoices')!;
+ expect(JSON.stringify(si)).toContain('to_review');
+ expect(JSON.stringify(si)).toContain('query_fields');
});
it('documents the sandbox host and staging header', () => {
From 91940c1bffab2be2a607019a96e6237a5647215d Mon Sep 17 00:00:00 2001
From: GallaGit <230304929+GallaGit@users.noreply.github.com>
Date: Wed, 14 Oct 2026 22:10:51 +0200
Subject: [PATCH 3/3] fix(adapters): mark Qonto unverified and encode
transaction id path param (#1013)
---
packages/backend/src/adapters/fr/qonto.json | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/packages/backend/src/adapters/fr/qonto.json b/packages/backend/src/adapters/fr/qonto.json
index 9527d8f40..039224d99 100644
--- a/packages/backend/src/adapters/fr/qonto.json
+++ b/packages/backend/src/adapters/fr/qonto.json
@@ -2,7 +2,7 @@
"slug": "qonto",
"name": "Qonto",
"description": "Qonto — French business account for SMBs and freelancers: organization and bank accounts, transactions, client and supplier invoices, clients and quotes. Official Business API v2, read-only, login:secret-key API key. 7 tools.",
- "instructions": "This connector reads your **Qonto** business account through the official Business API: organization and bank accounts, transactions, client invoices, supplier invoices, clients and quotes. It is **read-only**: every tool is a GET, so it cannot send transfers, add beneficiaries, touch cards or create, edit or delete invoices.\n\n**Getting the credentials**\n1. Sign in to the Qonto web app (https://app.qonto.com) and, if you have several organizations, pick the one to connect.\n2. Open **Integrations & Partnerships → API key** and click **Generate** if no secret key exists yet.\n3. Put the **login** (sign-in, e.g. `pied-piper-7132`) in `QONTO_LOGIN` and the **secret key** in `QONTO_SECRET_KEY`.\n\n**How authentication works**: Qonto expects `Authorization: :`. This looks like HTTP Basic but is not: no Base64 and no `Bearer` prefix. A 401 almost always means a wrong login or secret.\n\n**Bank data is sensitive.** The connector sees every bank account of the organization. Assign it only to MCP servers whose users are allowed to see the company's bank accounts and transactions.\n\n**Workflow**: call `qonto_get_organization` first to get the bank account `id` (or IBAN); `qonto_list_transactions` lists one account at a time; passing `bank_account_id` or `iban` is recommended (whether Qonto rejects a call without them is pending verification).\n\n**Pagination**: list tools take `page` and `per_page` (1 to 100, default 100); responses carry `meta.next_page` and `meta.total_pages`.\n\n**Amounts**: transactions expose `amount` and `amount_cents`; prefer the cents for arithmetic.\n\n**Sandbox**: create an application on the Qonto Developer Portal (https://developers.qonto.com) to get a sandbox organization and a personal staging token. After install, edit the connector: set the base URL to `https://thirdparty-sandbox.staging.qonto.co/v2` and add the header `X-Qonto-Staging-Token: ` (case-sensitive). Without it, sandbox calls return a OneLogin HTML page instead of JSON. The staging token is not accepted in production.\n\n**Cloud reachability**: thirdparty.qonto.com is public with a valid certificate.",
+ "instructions": "This connector reads your **Qonto** business account through the official Business API: organization and bank accounts, transactions, client invoices, supplier invoices, clients and quotes. It is **read-only**: every tool is a GET, so it cannot send transfers, add beneficiaries, touch cards or create, edit or delete invoices.\n\n**Getting the credentials**\n1. Sign in to the Qonto web app (https://app.qonto.com) and, if you have several organizations, pick the one to connect.\n2. Open **Integrations & Partnerships → API key** and click **Generate** if no secret key exists yet.\n3. Put the **login** (sign-in, e.g. `pied-piper-7132`) in `QONTO_LOGIN` and the **secret key** in `QONTO_SECRET_KEY`.\n\n**How authentication works**: Qonto expects `Authorization: :`. This looks like HTTP Basic but is not: no Base64 and no `Bearer` prefix. A 401 almost always means a wrong login or secret.\n\n**Bank data is sensitive.** The connector sees every bank account of the organization. Assign it only to MCP servers whose users are allowed to see the company's bank accounts and transactions.\n\n**Workflow**: call `qonto_get_organization` first to get the bank account `id` (or IBAN); `qonto_list_transactions` lists one account at a time; passing `bank_account_id` or `iban` is recommended (whether Qonto rejects a call without them is pending verification).\n\n**Pagination**: list tools take `page` and `per_page` (1 to 100, default 100); responses carry `meta.next_page` and `meta.total_pages`.\n\n**Amounts**: transactions expose `amount` and `amount_cents`; prefer the cents for arithmetic.\n\n**Unverified.** This adapter has not been exercised against a live Qonto account yet. Two points still need confirming with a real account: the exact `Authorization: :` header format, and whether `/transactions` requires `bank_account_id` or `iban`. A correction from anyone running it against a real organization is welcome.\n\n**Sandbox**: create an application on the Qonto Developer Portal (https://developers.qonto.com) to get a sandbox organization and a personal staging token. After install, edit the connector: set the base URL to `https://thirdparty-sandbox.staging.qonto.co/v2` and add the header `X-Qonto-Staging-Token: ` (case-sensitive). Without it, sandbox calls return a OneLogin HTML page instead of JSON. The staging token is not accepted in production.\n\n**Cloud reachability**: thirdparty.qonto.com is public with a valid certificate.",
"region": "fr",
"category": "banking",
"icon": "qonto",
@@ -137,7 +137,8 @@
},
"endpointMapping": {
"method": "GET",
- "path": "/transactions/{id}"
+ "path": "/transactions/{id}",
+ "encodePathParams": true
}
},
{