bunq Partner MCP
OfficialThis MCP server lets AI assistants manage bunq Partner API operations through natural language, including the full partner onboarding and user lifecycle.
Check and refresh bunq sessions and verify the active sandbox/production environment.
Create, list, and configure OAuth clients and callback URLs.
Provision new users, monitor provision status, cancel provisions, and reset expired tokens.
Create per-user sessions and manage webhook notification filters and failed deliveries.
Complete KYC/onboarding: addresses, personal details, tax residency, nationality, identity verification, and document uploads.
Create and list EUR bank accounts and external currency accounts.
Create, list, and inspect payments.
Order, list, update, and inspect credit/debit cards, including encrypted PAN and CVC2 operations.
List and respond to compliance inquiries with attachments or text answers.
Allows AI assistants to drive the entire partner onboarding flow — provisioning users, KYC, accounts, payments, cards, and compliance — through natural language conversation via the bunq Partner API.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bunq Partner MCP Provision a new user with email test@example.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
bunq Partner MCP
An MCP (Model Context Protocol) server that connects AI assistants like Claude to the bunq Partner API. Once set up, you can drive the entire partner onboarding flow — provisioning users, KYC, accounts, payments, cards, and compliance — through natural language conversation.
What you can do
After connecting, you can ask Claude things like:
"Provision a new user with email jan@example.nl and phone +31612345678"
"Check the status of provision 4521"
"Create a EUR bank account for user 8823"
"Make a payment of €50 from account 12 to IBAN NL91ABNA0417164300"
"Show me all open compliance inquiries for user 9002"
"Register a webhook for mutations on user 8823 pointing to https://myapp.com/webhooks"
Claude handles the full auth lifecycle, request signing, token management, and status polling automatically.
Related MCP server: you-need-an-advisor-mcp
Prerequisites
A bunq Partner API key (provided by bunq)
Claude Desktop with a Pro or Team subscription
Setup
1. Clone and build
git clone https://github.com/bunq/partner-mcp.git
cd partner-mcp
npm install
npm run build2. Add to Claude Desktop
Edit your Claude Desktop config file:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"bunq-partner": {
"command": "node",
"args": ["/absolute/path/to/partner-mcp/dist/index.js"],
"env": {
"BUNQ_API_KEY": "your_partner_api_key_here",
"BUNQ_ENV": "sandbox"
}
}
}
}Replace /absolute/path/to/partner-mcp with the actual path where you cloned the repo.
3. Restart Claude Desktop
Quit and reopen Claude Desktop. You should see the bunq tools available.
4. Verify the connection
Ask Claude: "Check my bunq session info" — it should respond with your authenticated user ID and environment.
Environments
| Base URL |
|
|
|
|
Always test in sandbox first. Sandbox API keys contain a sandbox_ prefix.
Sessions for provisioned users
Calls on behalf of a provisioned user (KYC, accounts, payments, cards, inquiries, freeze) must use that user's own session, not your partner session.
When
get_provisionshowsACTIVE, callcreate_user_sessionwith itsprovision_id.The server reads the provision's credential token itself, creates the user's installation, device and session, and keeps them. The token never reaches the conversation. The tool returns only
user_idanduser_api_key_id.Pass that
user_idto every per-user tool. The server picks the matching session. Useuser_api_key_idonly to register that user's webhooks withset_notification_filters.
A per-user tool called before create_user_session fails with a message that tells you to create the session first.
What stays out of the conversation
Tool results never contain a credential token (token_value), a full card number (only the last 4 digits) or a CVC code.
Optional settings
Variable | Default | Meaning |
|
| Keeps the key pairs, installations and sessions in a local file, so a restart does not register a new device or lose user sessions. |
|
| Where that file goes. It holds private keys and tokens and is written with mode |
|
| HTTP timeout per call. |
The server checks the X-Bunq-Server-Signature of every successful response and refuses an unsigned or wrongly signed one.
Updating
When a new version is released:
cd partner-mcp
git pull
npm install
npm run buildThen restart Claude Desktop.
Available tools
The full API documentation — covering auth, OAuth, user provision, onboarding & KYC, webhooks, monetary accounts, payments, devices, cards, and compliance — lives in GitBook:
Project structure
partner-mcp/
├── src/
│ ├── index.ts # MCP server entry point (stdio transport)
│ ├── bunq-client.ts # HTTP client, partner and user sessions, signatures
│ ├── state-store.ts # Optional state file for keys and sessions
│ ├── encryption.ts # Application-layer request/response encryption
│ ├── tools.ts # Tool definitions (MCP schemas)
│ ├── operations.ts # One entry per API tool: method, path, session, body
│ └── handler.ts # Argument checks, custom tools, operation runner
├── test/ # Unit tests (node:test), incl. the swagger parity test
├── partner-api-swagger.yaml # Maintained OpenAPI spec
├── package.json
└── tsconfig.jsonSupport
Available Tools
45 toolsclose_provisionB
Cancels a user provision. Sets status to CANCELLED.
Inputs: provision_id (required).
create_bank_accountC
Creates a EUR IBAN bank account (MonetaryAccountBank) for a provisioned user.
Inputs: user_id (required), currency, description.
create_card_cvc2B
Generates a new CVC2 security code for a card. This is an encrypted endpoint — the request is end-to-end encrypted on top of TLS.
Inputs: card_id (required), user_id (required), type.
create_card_panB
Generates and retrieves the primary account number (PAN) for a card. This is an encrypted endpoint — the request is end-to-end encrypted on top of TLS.
Inputs: card_id (required), user_id (required).
create_credit_cardA
Orders a new Mastercard credit card for a user. Use order_status=VIRTUAL_DELIVERY for immediate virtual card, or NEW_CARD_REQUEST_RECEIVED for physical delivery by post.
Inputs: user_id (required), second_line (required), product_type (required), name_on_card, +2 more.
create_debit_cardA
Orders a new Mastercard debit card for a user. Use order_status=VIRTUAL_DELIVERY for immediate virtual card, or NEW_CARD_REQUEST_RECEIVED for physical delivery by post.
Inputs: user_id (required), second_line (required), product_type (required), name_on_card, +3 more.
create_external_accountB
Creates a non-EUR external monetary account (MonetaryAccountExternal) via CurrencyCloud.
Inputs: user_id (required), currency (required), service, description, +1 more.
create_oauth_clientA
Creates a new OAuth client for the partner account. Required before provisioning any users.
Inputs: no named parameters.
create_paymentB
Creates a payment from a monetary account. For provisioned users without PSD2 access, only internal transfers between Eva and the partner are allowed. Description is limited to 140 characters.
Inputs: amount (required), user_id (required), account_id (required), description (required), +4 more.
create_provisionA
Provisions a new UserPerson under the partner account. Kicks off the full onboarding flow. Returns a provision_id to monitor progress via get_provision. The provision goes through sub-statuses: PENDING_PROCESS_USER → PENDING_PROCESS_RELATION_USER → PENDING_PROCESS_OAUTH_REQUEST → PENDING_PROCESS_USER_ONBOARDING. When ACTIVE, a credential.token_value is returned — this is Eva's API key. It expires in 1h (sandbox) / 4h (production): create a session immediately with create_user_session.
Inputs: email (required), phone_number (required), external_uuid (required), products, +1 more.
create_user_sessionA
Creates a session on behalf of a provisioned user using their credential.token_value (obtained from get_provision when status=ACTIVE). Returns a session token and UserApiKey.id — use this session token for all subsequent calls on behalf of that user. Must be called within 1h (sandbox) / 4h (production) of the token being issued.
Inputs: credential_token (required).
get_attachmentA
Gets metadata and download URLs for a previously uploaded attachment.
Inputs: user_id (required), attachment_id (required).
get_cardB
Gets details of a specific card including status, limits, and expiry date.
Inputs: card_id (required), user_id (required).
get_card_cvc2A
Gets the details of a specific generated CVC2 code. This is an encrypted endpoint.
Inputs: card_id (required), user_id (required), generated_cvc2_id (required).
get_identity_verificationA
Gets the identity verification session details including the SDK token and status. Use the token field to initialise the Incode SDK in your app.
Inputs: user_id (required), session_id (required).
get_monetary_accountB
Gets details of a specific monetary account including balance and IBAN.
Inputs: user_id (required), account_id (required).
get_oauth_clientA
Gets details (client_id, secret, callback URLs) for a specific OAuth client.
Inputs: oauth_client_id (required).
get_paymentC
Gets details of a specific payment.
Inputs: user_id (required), account_id (required), payment_id (required).
get_provisionA
Gets the current status and details of a user provision. Poll this after create_provision to track progress. When status=ACTIVE and credential.token_value is present, immediately call create_user_session — the token expires in 1h (sandbox) / 4h (production).
Inputs: provision_id (required).
get_session_infoA
Returns the current session status, authenticated user ID, and active environment (sandbox/production). Useful to verify the connection is working before other calls.
Inputs: no named parameters.
get_user_inquiryB
Gets full details of a compliance inquiry including all entries and their status.
Inputs: user_id (required), inquiry_id (required).
link_document_identificationA
Links an uploaded attachment to a document type for KYC purposes (e.g. CRYPTO_KYC_QUESTIONNAIRE). Call after upload_attachment.
Inputs: user_id (required), document_type (required), document_attachment_id (required), document_country_of_issuance (required), +1 more.
list_card_cvc2B
Lists all generated CVC2 codes for a card. This is an encrypted endpoint.
Inputs: card_id (required), user_id (required).
list_cardsB
Lists all cards (credit and debit) for a user.
Inputs: user_id (required).
list_monetary_accountsB
Lists all monetary accounts for a user.
Inputs: user_id (required).
list_notification_failuresA
Lists failed webhook deliveries for the partner's company user. The userId should be the UserCompany.id — this returns failures for all underlying provisioned users. Each record includes user_id (which provisioned user the failure belongs to) and user_requested_id (set when the filter was created via an API key, otherwise null).
Inputs: user_id (required).
list_oauth_clientsA
Lists all OAuth clients for the partner account.
Inputs: no named parameters.
list_paymentsA
Lists all payments (incoming and outgoing) for a monetary account.
Inputs: user_id (required), account_id (required).
list_provisionsB
Lists all partner user provisions with optional filtering.
Inputs: status, external_uuid.
list_user_inquiriesA
Lists compliance information inquiries for a provisioned user. Use status=EXPECTING_REPLY_FROM_USER to find open inquiries requiring action.
Inputs: user_id (required), status, purpose.
refresh_sessionA
Force-refreshes the bunq session token. Use this if you receive authentication errors.
Inputs: no named parameters.
register_oauth_callback_urlB
Registers an OAuth callback URL for a specific OAuth client.
Inputs: url (required), oauth_client_id (required).
reset_provision_tokenA
Requests a new credential API key for a provision whose token was lost, expired, or revoked. Sets status to TOKEN_RESET_REQUESTED. Poll get_provision until a new credential.token_value appears, then call create_user_session immediately.
Inputs: provision_id (required).
respond_to_inquiry_entryA
Submits an answer for a specific inquiry entry on behalf of Eva. Provide either attachment IDs (upload via upload_attachment first) or a free-text answer, or both. Only PENDING entries can be answered. After submission the entry moves to WAITING_FOR_REVIEW.
Inputs: user_id (required), entry_id (required), inquiry_id (required), answer, +1 more.
retry_notification_failuresB
Retries delivery of up to 100 failed webhook notifications by their failure IDs.
Inputs: user_id (required), failure_ids (required).
set_address_mainB
Sets the main (residential) address for a provisioned user during onboarding.
Inputs: city (required), street (required), user_id (required), postal_code (required), +2 more.
set_address_postalB
Sets the postal address for a provisioned user during onboarding.
Inputs: city (required), street (required), user_id (required), postal_code (required), +2 more.
set_nationalityA
Submits nationality information for a provisioned user. Required within 90 days.
Inputs: user_id (required), nationalities (required).
set_notification_filtersA
Sets webhook URLs for a user. ⚠️ This REPLACES all existing filters — always include the full desired list in one call. To add one filter, fetch the existing ones first and include them all. To remove all, pass an empty array. Categories: PARTNER_USER_PROVISION, USER_ONBOARDING, USER_INFORMATION_INQUIRY, MUTATION, PAYMENT, CARD, CARD_TRANSACTION_SUCCESSFUL, CARD_TRANSACTION_FAILED.
Inputs: filters (required), user_id (required).
set_tax_residentA
Submits tax residency information for a provisioned user. Required within 90 days.
Inputs: user_id (required), tax_residents (required).
start_identity_verificationA
Creates an identity verification session using the Incode SDK. Returns a session ID. Follow up with get_identity_verification to obtain the SDK token, pass it to the Incode SDK, then call submit_identity_verification once the SDK flow completes.
Inputs: user_id (required), purpose, provider.
submit_identity_verificationA
Notifies bunq that the Incode SDK flow is complete and the identity verification result is ready to be processed. Call this after the SDK returns a successful completion callback.
Inputs: user_id (required), session_id (required).
update_cardA
Updates a card's status, spending limits, or PIN. Use to activate a card after delivery, block/unblock it, or report it lost/stolen.
Inputs: card_id (required), user_id (required), status, card_limit, +2 more.
update_user_personB
Updates personal information for a provisioned user: name and date of birth.
Inputs: user_id (required), last_name (required), first_name (required), date_of_birth (required), +1 more.
upload_attachmentB
Uploads a file attachment for a provisioned user. The attachment ID can then be passed to respond_to_inquiry_entry via all_attachment_id to submit documents for a compliance inquiry. Supported types: image/png, image/jpeg, image/gif, application/pdf. Note: the actual file bytes must be sent as raw binary — provide the file path.
Inputs: user_id (required), description (required), content_type (required), base64_content (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 45 tools
Most tools have clearly distinct purposes, e.g., provisioning, KYC, banking, cards. Some potential confusion exists between set_nationality and set_tax_resident, or start_identity_verification vs. get_identity_verification vs. submit_identity_verification, but descriptions clarify the flow. Overall, an agent can distinguish tools with reasonable accuracy.
Tool names follow a consistent verb_noun pattern (e.g., create_provision, get_card, list_payments). Minor deviations like 'register_oauth_callback_url' vs. 'create_oauth_client' are present but not disruptive. No mixing of casing styles.
45 tools is high for a single server. While the domain is broad (provisioning, KYC, accounts, cards, payments, compliance, OAuth, notifications), many tools could be consolidated (e.g., three CVC2 tools, multiple identity verification tools). The set feels slightly bloated.
The tool surface covers the full lifecycle for user provisioning, KYC, banking, cards, payments, and compliance inquiries. Minor gaps exist: no tool to close a bank account, delete a card, or manage OAuth clients beyond creation. Overall, core workflows are well-supported.
Maintenance
Related MCP Connectors
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
KVK Handelsregister AI Connect: hosted MCP server for the Dutch business register.
Related MCP Servers
- AlicenseAqualityAmaintenanceLets AI assistants read and manage a self-hosted Actual Budget: accounts, transactions, budgets, categories, payees, rules, schedules and reports. Runs over stdio for Claude Desktop and Claude Code, or over HTTP with Bearer or OIDC auth for LibreChat and LobeChat.151,864 npm77MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that connects AI assistants to YNAB budgets, enabling natural language queries about finances backed by full API coverage and built-in YNAB methodology knowledge.1MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that enables AI assistants to match users with capital providers for business loans, real estate, and asset tokenization through a conversational intake process.MIT
- FlicenseNot gradedqualityCmaintenanceAn MCP server that enables AI assistants to interact with OpenProject, listing projects and work packages and managing resources through natural language.-