Labsco
alexey-pelykh logo

QontoCtl

3

from alexey-pelykh

CLI and MCP server for the Qonto business banking API — manage transactions, invoices, clients, transfers, and more

🔥🔥🔥✓ VerifiedFreeAdvanced setup

QontoCtl: The Complete CLI & MCP for Qonto

npm downloads

CLI and MCP server for the Qonto banking API.

This project is brought to you by Alexey Pelykh.

What It Does

QontoCtl lets AI assistants (Claude, etc.) interact with Qonto through the Model Context Protocol. It can:

  • Organizations — retrieve organization details and settings
  • Accounts — list, create, update, close bank accounts; download IBAN certificates
  • Transactions — list, search, filter bank transactions; manage transaction attachments
  • Bank Statements — list, view, and download bank statements
  • Labels — manage transaction labels and categories
  • Memberships — view team members, show current membership, invite new members
  • SEPA Beneficiaries — list, add, update, trust/untrust SEPA beneficiaries
  • SEPA Transfers — list, create, cancel transfers; download proofs; verify payees
  • Internal Transfers — create transfers between accounts in the same organization
  • Bulk Transfers — list and view bulk transfer batches
  • Recurring Transfers — list and view recurring transfers
  • Terminals (POS) — list Qonto Terminals and initiate terminal payments
  • Products — list catalogue products
  • Clients — list, create, update, delete clients
  • Client Invoices — full lifecycle: create, update, finalize, send, mark paid, cancel, upload files
  • Quotes — create, update, delete, send quotes
  • Credit Notes — list and view credit notes
  • Supplier Invoices — list, view, and bulk-create supplier invoices
  • Requests — list organization requests
  • Attachments — upload and view attachments
  • E-Invoicing — retrieve e-invoicing settings

MCP Integration

QontoCtl implements the Model Context Protocol (MCP), letting AI assistants interact with your Qonto account through natural language.

MCP Client Configuration

Claude Desktop

Add to your Claude Desktop configuration (claude_desktop_config.json):

{
    "mcpServers": {
        "qontoctl": {
            "command": "npx",
            "args": ["qontoctl", "mcp"]
        }
    }
}
Claude Code
claude mcp add qontoctl -- npx qontoctl mcp
Cursor

Add to .cursor/mcp.json in your project root:

{
    "mcpServers": {
        "qontoctl": {
            "command": "npx",
            "args": ["qontoctl", "mcp"]
        }
    }
}
Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
    "mcpServers": {
        "qontoctl": {
            "command": "npx",
            "args": ["qontoctl", "mcp"]
        }
    }
}

Pointing MCP at a non-default config file

The MCP server has no CLI flags. To load credentials from a config file other than ~/.qontoctl.yaml, set QONTOCTL_CONFIG_FILE in the host's env block:

{
    "mcpServers": {
        "qontoctl": {
            "command": "npx",
            "args": ["qontoctl", "mcp"],
            "env": {
                "QONTOCTL_CONFIG_FILE": "/abs/path/to/qontoctl.yaml",
            },
        },
    },
}

The path is captured at server startup. See docs/configuration.md for the full resolution chain.

Available MCP Tools

ToolDescription
Organization
org_showShow organization details including name, slug, and bank accounts
Accounts
account_listList all bank accounts for the organization
account_showShow details of a specific bank account
account_iban_certificateDownload IBAN certificate PDF for a bank account
account_createCreate a new bank account
account_updateUpdate an existing bank account
account_closeClose a bank account
Transactions
transaction_listList transactions for a bank account with optional filters
transaction_showShow details of a specific transaction
transaction_attachment_listList attachments for a transaction
transaction_attachment_addAttach a file to a transaction
transaction_attachment_removeRemove attachment(s) from a transaction
Statements
statement_listList bank statements with optional filters
statement_showShow details of a specific bank statement
Labels
label_listList all labels in the organization
label_showShow details of a specific label
Memberships
membership_listList all memberships in the organization
membership_showShow the current authenticated user's membership
membership_inviteInvite a new member to the organization
SEPA Beneficiaries
beneficiary_listList SEPA beneficiaries in the organization
beneficiary_showShow details of a specific SEPA beneficiary
beneficiary_addCreate a new SEPA beneficiary
beneficiary_updateUpdate an existing SEPA beneficiary
beneficiary_trustTrust one or more SEPA beneficiaries
beneficiary_untrustUntrust one or more SEPA beneficiaries
SEPA Transfers
transfer_listList SEPA transfers with optional filters
transfer_showShow details of a specific SEPA transfer
transfer_createCreate a SEPA transfer
transfer_cancelCancel a pending SEPA transfer
transfer_proofDownload SEPA transfer proof PDF
transfer_verify_payeeVerify a payee (Verification of Payee / VoP)
transfer_bulk_verify_payeeBulk verify payees (VoP)
Internal Transfers
internal_transfer_createCreate an internal transfer between two bank accounts
Bulk Transfers
bulk_transfer_listList bulk transfers
bulk_transfer_showShow details of a specific bulk transfer
bulk_transfer_createCreate a bulk SEPA transfer (auto-resolves VoP via bulk_verify_payee)
Recurring Transfers
recurring_transfer_listList recurring transfers
recurring_transfer_showShow details of a specific recurring transfer
Terminals (POS)
terminal_listList Qonto Terminals linked to the organization
terminal_payment_createInitiate a payment on a terminal (returns 202 Accepted)
Products
product_listList catalogue products with optional pagination and sort
Clients
client_listList clients with optional pagination
client_showShow details of a specific client
client_createCreate a new client
client_updateUpdate an existing client
client_deleteDelete a client
Client Invoices
client_invoice_listList client invoices with optional filters
client_invoice_showShow details of a specific client invoice
client_invoice_createCreate a draft client invoice with client and line items
client_invoice_updateUpdate a draft client invoice
client_invoice_deleteDelete a draft client invoice
client_invoice_finalizeFinalize a client invoice (assign number)
client_invoice_sendSend a client invoice to the client via email
client_invoice_mark_paidMark a client invoice as paid
client_invoice_unmark_paidUnmark a client invoice paid status
client_invoice_cancelCancel a finalized client invoice
client_invoice_uploadUpload a file to a client invoice
client_invoice_upload_showShow upload details for a client invoice
Quotes
quote_listList quotes with optional filters
quote_showShow details of a specific quote
quote_createCreate a new quote with client and line items
quote_updateUpdate an existing quote
quote_deleteDelete a quote
quote_sendSend a quote to the client via email
Credit Notes
credit_note_listList credit notes in the organization
credit_note_showShow details of a specific credit note
Supplier Invoices
supplier_invoice_listList supplier invoices with optional filters
supplier_invoice_showShow details of a specific supplier invoice
supplier_invoice_bulk_createCreate supplier invoices by uploading files
Requests
request_listList all requests in the organization
SCA Sessions
sca_session_showShow the status of an SCA session (waiting / allow / deny)
sca_session_mock_decisionSimulate an SCA decision in the Qonto sandbox (sandbox-only)
Attachments
attachment_uploadUpload an attachment file (PDF, JPEG, PNG)
attachment_showShow details of a specific attachment
E-Invoicing
einvoicing_settingsRetrieve e-invoicing settings for the organization

Example Prompts

Once configured, you can ask your AI assistant things like:

  • "Show my Qonto account balances"
  • "List recent transactions over 1000 EUR"
  • "What were last month's card payments?"
  • "Show all team members in my organization"
  • "List bank statements for January 2026"
  • "Create a summary of this week's debits"

SCA Continuation

Some Qonto write operations — creating a transfer, modifying a card, approving a request — require Strong Customer Authentication (SCA): the user has to approve the request in the Qonto mobile app before it executes. QontoCtl wraps every SCA-gated MCP write tool with a continuation flow so the LLM client never has to reimplement polling.

How a wrapped write tool behaves

When an SCA-gated tool (e.g. transfer_create, card_create, beneficiary_trust, request_approve) hits a 428 SCA challenge, the wrapper polls the SCA session inline. If the user approves within the polling window, the tool returns the operation's success result transparently — the LLM never sees the SCA round-trip. If polling times out (or polling is disabled), the tool returns a structured SCA-pending response carrying the session token and instructions to continue.

Every wrapped tool exposes two optional input fields for this flow:

  • wait — maximum seconds to poll inline before falling back to the pending response.
  • sca_session_token — bind a previously approved SCA challenge to a retry.

The wait knob

ValueBehavior
30 (default)Poll for up to 30 seconds, then fall back to the structured pending response.
1120Poll for the specified number of seconds (capped at 120).
0 or falseSkip polling entirely. Return the SCA-pending response immediately on the first 428.

The 120 upper bound is the hard ceiling enforced via Zod at the input boundary. The practical ceiling is your MCP host's request timeout — Claude Desktop hardcodes ≈ 60 s and Cursor's effective limit is ≈ 30 s, so values above those will surface as host-side timeouts before the wrapper resolves. Use a small wait (e.g. 5-10) when the LLM expects the user to be present and willing to approve immediately. Use wait: false (or wait: 0) for pure two-step flows where the LLM and the user converse out-of-band between the SCA challenge and the retry.

Two-step fallback (out-of-band continuation)

When polling does not resolve, the SCA-pending response carries:

  • A user-facing message: "SCA required. The user must approve this operation on their Qonto mobile app."
  • A Session token: <token> line (token validity: 15 minutes from issuance).
  • Step-by-step instructions to continue.

The LLM (or the user) can then:

  1. Poll session status with the sca_session_show tool, passing the captured token. It returns waiting, allow, or deny.
  2. Retry the original tool once the status is allow, passing the same parameters plus sca_session_token: "<token>". The wrapper invokes the operation exactly once with the token bound — no second poll happens.

PSD2 dynamic linking. The SCA session token is bound to the original request parameters (amount, payee). Reusing a token against a different operation is rejected by Qonto. Reissue an SCA challenge by calling the original tool again whenever the parameters need to change.

Caller-supplied retry (sca_session_token)

When sca_session_token is set on a wrapped write tool, the wrapper:

  • Invokes the operation exactly once.
  • Skips polling entirely.
  • Forwards the token via the X-Qonto-Sca-Session-Token header.

This is the path used by step (2) of the two-step fallback. It is also useful when the LLM client implements its own polling cadence and only needs the wrapper to retry with an already-captured approval.

Sandbox testing

Sandbox accounts cannot enroll a real paired device, so SCA challenges in sandbox use a mock flow. After receiving a pending response, simulate the user's decision with the sca_session_mock_decision tool (sandbox-only — refuses to run when no staging token is configured). See docs/sandbox-testing.md for the full sandbox setup.

Migration note

Earlier QontoCtl builds (pre-@qontoctl/mcp SCA continuation) returned a free-form text response on 428 with no continuation hooks. Callers parsing that response should adopt the structured flow:

BeforeAfter
Free-form text mentioned the SCA endpoint but offered no MCP-exposed way to continue.The SCA-pending response is still text content but its shape is stable: Session token: <token> is the canonical line; sca_session_show is the polling API.
Polling required driving the Qonto HTTP API directly.Use the sca_session_show MCP tool.
Re-running the operation orphaned the prior approval.Retry the original tool with the captured sca_session_token parameter — the prior approval is bound to that retry.
No way to opt-in to inline polling — every 428 was a dead end.Pass wait: <seconds> (1-120) to poll inline; tools default to 30s. Pass wait: false for the explicit two-step flow.

The pending response's textual format is stable, so callers that need to extract the token programmatically can match against the Session token: line — but using sca_session_show directly avoids relying on the response prose.

Debug Mode

The --verbose and --debug flags enable wire-level logging to stderr:

qontoctl --verbose transaction list   # request/response summaries
qontoctl --debug transaction list     # full headers and response bodies

Security note: --debug logs full API response bodies. Known sensitive fields (IBAN, BIC, balance) are automatically redacted, but responses may still contain other financial data. Do not use --debug in shared environments or pipe debug output to files accessible by others.

Disclaimer

qontoctl is an independent project not affiliated with, endorsed by, or officially connected to Qonto or Qonto SAS.

Qonto is a trademark of Qonto SAS.