revolut-merchant-mcp
This server acts as a Model Context Protocol (MCP) interface for the Revolut Merchant API, allowing AI assistants to read and manage customers, payment methods, orders, subscriptions, plans, and webhooks — with write operations gated by default.
Customers:
Read: List customers (optionally by email), retrieve customer details by ID
Write (gated): Create, update, delete customers
Payment Methods:
Read: List and retrieve payment methods
Write (gated): Update and delete payment methods
Orders:
Read: List recent orders (with optional limit), retrieve order details by ID
Write (gated): Create, update, capture, cancel, pay, refund, and increment authorisation for orders
Subscriptions:
Read: List subscriptions (optionally by customer ID), retrieve subscription and cycle details
Write (gated): Create, update, cancel subscriptions; change plan; update renewal date
Plans:
Read: List plans, retrieve plan details (including variations) by ID
Write (gated): Create new plans
Webhooks:
Read: List and retrieve webhook details
Write (gated): Create, update, delete webhooks; rotate signing secrets
Safe defaults: Runs in sandbox mode by default; writes are disabled unless REVOLUT_MCP_ALLOW_WRITES=true is set; production access requires explicit opt-in via REVOLUT_I_UNDERSTAND_PRODUCTION=true.
Manages Revolut Merchant API resources: customers, orders, subscriptions, and plans, enabling payment acceptance and subscription management.
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., "@revolut-merchant-mcpshow my recent orders"
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.
revolut-merchant-mcp
A Model Context Protocol (MCP) server for the Revolut Merchant API — letting MCP-aware AI assistants (Claude Desktop, Cursor, agent harnesses) read and manage Revolut customers, payment methods, orders, subscriptions, plans, and webhooks.
Why this exists. The existing community Revolut MCP wraps the Revolut Business API (accounts, balances, transfers). This server targets the Merchant API — the surface you use to accept payments and run subscriptions — which had no MCP server until now.
Status: alpha / proof-of-concept. Sandbox-first, read-only by default.
Features
Broad Merchant API coverage across six domains. Read tools are always
registered; write (mutating) tools are registered only when
REVOLUT_MCP_ALLOW_WRITES=true — so the default posture is read-only.
Domain | Read tools (always on) | Write tools (gated by |
Customers |
|
|
Payment methods (customer-nested) |
|
|
Orders |
|
|
Subscriptions |
|
|
Plans |
|
|
Webhooks |
|
|
That's 14 read tools and 21 write tools (35 total).
Safe defaults: sandbox unless you explicitly opt into production; writes disabled unless explicitly enabled; idempotency keys + transient-error retry in the transport layer.
Related MCP server: invoiceninja-mcp
Install
# with uv (recommended)
uv pip install -e ".[dev]"
# or pip
pip install -e ".[dev]"Configure
Copy .env.example and set your sandbox key:
Variable | Required | Default | Notes |
| ✅ | — | Merchant API secret (sandbox or live) |
|
| Sent as | |
|
|
| |
|
| Required to run against production | |
|
| Register the create/cancel tools |
Sandbox keys come from the Revolut Sandbox Business dashboard (Merchant API).
Run
REVOLUT_MERCHANT_SECRET_KEY=sk_sandbox_... revolut-merchant-mcpThe server speaks MCP over stdio.
Claude Desktop / Cursor
{
"mcpServers": {
"revolut-merchant": {
"command": "revolut-merchant-mcp",
"env": {
"REVOLUT_MERCHANT_SECRET_KEY": "sk_sandbox_...",
"REVOLUT_SANDBOX": "true"
}
}
}
}Architecture
config.py env → Config (sandbox/prod guard, write gate)
client.py async transport: auth, versioning, idempotency, retry, errors
operations/ one module per domain (customers, orders, subscriptions,
plans, webhooks); each holds framework-free async fns plus a
register(mcp, client, allow_writes, safe) that wires its tools
server.py FastMCP wrapper — iterates the domain registrars (writes gated)The pure functions in operations/ have no MCP dependency, so the API layer
is fully testable with respx and reusable outside the server. Payment methods
are customer-nested (/customers/{id}/payment-methods) and so live in the
customers module.
Develop
ruff check .
pytestTests mock the Revolut sandbox host with respx — no live keys, no network.
Safety notes
This server can mutate live data (customers, payment methods, orders, subscriptions, plans, and webhooks — including refunds and order capture) when writes are enabled against a production key. Production and writes are both off by default and each requires an explicit opt-in.
Treat your Merchant secret like any payment credential. Prefer a sandbox key for anything agent-driven.
License
MIT © Sherman Studio Ltd. Not affiliated with or endorsed by Revolut.
Available Tools
8 toolsget_customerC
Retrieve a single Merchant customer by its id.
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It only states the basic operation but does not disclose error behavior, permissions, or response format. Very minimal for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no waste. However, given no annotations and minimal info, it borders on underspecification rather than conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple retrieval by ID, the description is adequate but lacks any context about errors, return values, or pagination. No output schema exists to compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% for the parameter 'customer_id'. Description adds no details about format, length, or valid values beyond 'by its id'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Retrieve a single Merchant customer by its id', using a specific verb and resource. Distinguishes from sibling tools like get_order or list_customers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives like list_customers for multiple customers. Agent must infer that this is for a single customer retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_orderB
Retrieve a single Merchant order by its id.
| Name | Required | Description | Default |
|---|---|---|---|
| order_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It only states 'Retrieve a single Merchant order', which is minimal. No mention of side effects, authentication requirements, rate limits, or expected response traits. For a simple read operation this is acceptable but still lacking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no extraneous words. It is front-loaded with the core action and resource. Every word is necessary and contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description does not mention what the tool returns (e.g., the full order object). Also lacks any behavioral notes. For a simple retrieval tool with one parameter, it is partially complete but missing critical return value information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, meaning the description adds no information about the `order_id` parameter beyond what the schema provides (name and type). The parameter name 'order_id' is self-explanatory, but the description should clarify its format or source. This is a major gap as the agent has no additional context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Retrieve' and identifies the resource as a 'single Merchant order by its id'. It clearly distinguishes from sibling tools like list_orders (which returns multiple) and get_customer/get_plan/get_subscription (different entities).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when you have an order ID and need a single order, but provides no explicit guidance on when to use this vs alternatives, no when-not conditions, and no prerequisites. The usage context is clear but not elaborated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_planA
Retrieve a single plan, including its variations, by id.
| Name | Required | Description | Default |
|---|---|---|---|
| plan_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It adds value by noting the plan includes its variations, which is behavioral context. However, it does not mention return format, errors, or side effects, but for a simple read operation this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, directly to the point, no wasted words. Every part adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, description should explain return values. It mentions 'including its variations' but omits other fields, pagination, or error behavior. Adequate but not complete for a retrieval tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description adds meaning: the sole parameter plan_id is used for retrieval by id, and the resulting plan includes variations. This clarifies the parameter's purpose beyond the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool retrieves a single plan by id, including variations. Verb 'retrieve' and resource 'plan' are specific, and 'by id' distinguishes it from list_plans and other get tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when you have a plan id, but does not explicitly state when not to use or mention alternatives like list_plans for multiple plans. Lack of explicit guidance lowers the score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_subscriptionC
Retrieve a single subscription by its id.
| Name | Required | Description | Default |
|---|---|---|---|
| subscription_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry full behavioral disclosure. It only states the basic action (retrieve) without mentioning authentication requirements, rate limits, error behavior (e.g., what happens if ID not found), or any side effects. For a read operation, basic transparency is expected but not met.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence of 7 words with no fluff. It is front-loaded effectively. However, it is slightly too minimal—adding a brief phrase about return value or common usage would improve without sacrificing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (1 parameter, no output schema, no nested objects), the description is minimally adequate. However, it omits any mention of the return value or behavior on missing IDs. Considering sibling tools and the absence of output schema, a bit more completeness would be expected.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the description only mentions 'by its id' without explaining the format, constraints, or meaning of subscription_id. The schema property lacks a description, so the description should compensate but does not add detail beyond the parameter name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'retrieve' and the resource 'subscription', and specifies retrieval by ID. It distinguishes from list_subscriptions by indicating a single subscription, but does not differentiate from other get_* tools such as get_customer or get_order.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives, such as list_subscriptions or other get_* tools. The tool is implied only for cases where a specific subscription ID is known, but no explicit context or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_customersB
List Merchant customers, optionally filtered by exact email address.
| Name | Required | Description | Default |
|---|---|---|---|
| No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behaviors. It does not mention pagination, sorting, limits, read-only nature, or response format. The description carries full burden and is insufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with no extraneous words. Could be slightly more informative without losing conciseness, but current structure is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Without output schema or annotations, the description lacks expected details for a list operation, such as pagination, default order, or field descriptions. Not complete enough for reliable use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% coverage for descriptions. The description adds that the email filter is exact, but does not clarify case sensitivity or behavior when email is null. Partial compensation for schema gaps.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists Merchant customers with an optional email filter. It distinguishes from get_customer implicitly, but does not explicitly differentiate among siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions optional email filtering but provides no guidance on when to use this tool vs. alternatives like get_customer or other list tools. Usage context is implied, not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_ordersC
List recent Merchant orders.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It only says 'list', implying a read operation, but omits details such as whether it is destructive, any rate limits, pagination behavior, or what happens if no orders exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, which is concise, but it is too terse for the information needed. It lacks any structured presentation of key details like parameters or output, reducing its effectiveness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of output schema, no parameter descriptions, and no annotations, the description is incomplete. It does not explain the return format, pagination, or any ordering behavior, which is insufficient for a list operation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the parameter 'limit' is completely undocumented in both schema and description. The description does not mention the parameter or explain how it controls the result size, leaving the agent with no semantic guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'List recent Merchant orders' clearly states the action (list) and resource (orders). The term 'recent' adds scope, distinguishing it from 'get_order' which retrieves a single order. However, it does not explicitly differentiate from other list_* sibling tools beyond the resource name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like 'get_order'. The sibling names imply that this tool is for listing orders as opposed to retrieving a specific one, but the description does not state this or provide any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_plansB
List Merchant subscription plans.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description merely states 'List', implying a read operation, but without annotations it does not disclose any behavioral traits such as pagination, rate limits, or whether it returns full plan details or only summaries. No destructive or safety information is provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that is front-loaded with the verb and key information. There is no superfluous text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple, parameterless list tool, the description is adequate to understand its purpose. However, it could mention common details like pagination or ordering to fully prepare the agent, especially given sibling tools exist.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so the schema provides full coverage. The description adds a minor context ('Merchant subscription plans') beyond the name, meeting the baseline expectation for a parameterless tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action ('List') and resource ('Merchant subscription plans'), distinguishing it from sibling tools like 'get_plan' (single) or 'list_subscriptions' (different entity). However, it does not explain what 'Merchant' implies, leaving some ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like 'get_plan' or 'list_subscriptions'. There are no hints about prerequisites or scenarios where this tool is inappropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_subscriptionsC
List subscriptions, optionally filtered by customer id.
| Name | Required | Description | Default |
|---|---|---|---|
| customer_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It implies a read-only operation but fails to disclose behavior like pagination, sorting, rate limits, or scope of results. Only the basic purpose is conveyed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no wasted words. However, it is borderline too brief; a slightly longer description with more context would be more helpful without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, no annotations, and 0% schema description coverage, the description is incomplete. It does not explain return format, pagination, ordering, or any limits, which are important for a list tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The parameter 'customer_id' is described as an optional filter, but the description does not explain what value it expects (e.g., format, meaning) beyond the schema's type. Schema description coverage is 0%, so the description adds minimal semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and the resource 'subscriptions', and mentions optional filtering by customer id. However, it does not explicitly differentiate from sibling tools like 'get_subscription' beyond the resource name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like 'get_subscription' or other list tools. The mention of optional filtering by customer id is a usage hint but not sufficient guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
get_customer - First observed
get_order - First observed
get_plan - First observed
get_subscription - First observed
list_customers - First observed
list_orders - First observed
list_plans - First observed
list_subscriptions
TDQS
Scored across 8 tools
Each tool targets a distinct resource (customer, order, plan, subscription) and a distinct action (get single vs list multiple). There is no overlap in functionality.
All tools follow a consistent verb_noun pattern: get_<resource> for single retrieval and list_<resource> for listing. No mixing of conventions.
With 8 tools covering retrieval of four core merchant entities, the count is well-scoped and appropriate for a focused read-only interface.
The tool set lacks any mutation operations (create, update, delete), which are essential for a complete merchant workflow. Agents cannot create orders, subscriptions, or manage customers.
Maintenance
Related MCP Connectors
MCP server for Lemon Squeezy — stores, products, orders, subscriptions, license keys.
MCP server for Recurly — accounts, subscriptions, invoices, plans; cancel & pause subs.
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
MCP server for Modern Treasury — payment orders, transactions, counterparties and ledgers.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA comprehensive Model Context Protocol (MCP) server that provides complete access to the Recharge Storefront API endpoints. Enables AI assistants to manage subscriptions, customers, orders, and billing through a standardized interface.2MIT
- AlicenseBqualityDmaintenanceMCP server for Invoice Ninja v5 API. Enables AI assistants to manage clients, invoices, quotes, payments, and time tracking through natural language.3216 npm2MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for the YooKassa payment API, enabling AI assistants to manage payments, refunds, receipts, webhooks, and saved payment methods through natural language.MIT
- FlicenseNot gradedqualityBmaintenanceDemo MCP server that exposes order and customer data as read-only tools for AI assistants, simulating a business API or internal data source.-