MCP interface
Verified
In short
Section titled “In short”MitoOps provides a standard remote MCP server (Model Context Protocol) at /api/mcp, through which a compatible AI application fetches data itself. It sits on the same capabilities as REST — it is not a second interface with its own queries, it is a different way of asking the same question.
MCP is not a property of the model but of the application the model runs in (the client). Any application that supports remote MCP over HTTP with OAuth or with an access key can connect. Claude.ai is the production-verified client — its exact procedure is below; for any other application the general procedure in the next section applies. Clients we have not tested are not declared verified.
There are two ways to identify yourself:
- with an access key you issue in the application — for your own program, or a server calling a server;
- over OAuth, when the connecting AI application supports it — then you sign in yourself and pick, on the consent screen, what it may read.
Either way the token travels in the Authorization: Bearer header, and either way the same scope of permissions applies: what the key or the consent does not cover, no tool returns.
Connecting Claude.ai — verified step by step
Section titled “Connecting Claude.ai — verified step by step”Claude.ai does not connect to individual stores; it connects to MitoOps — the layer that already brings the data of all your stores together.
You need no key, no Client ID and no secret. Claude.ai discovers everything from the interface address.
- In Claude.ai open Settings → Customize → Connectors (on a Team plan an owner first adds it under Organization settings → Connectors).
- Click Add custom connector.
- In Name enter
MitoOps. - In URL paste the MCP address from the Settings → API & MCP screen — in the form
https://<your address>/api/mcp, for examplehttps://app.mitoops.com/api/mcp. - Leave Advanced settings empty: Claude.ai uses its own hosted client metadata (OAuth). Click Add.
- Click Connect on the connector.
- The MitoOps sign-in opens (including the second factor if you use one). Sign in.
- You see the consent screen: which application, which client, what it may read and which shops it applies to.
- Review the scopes. The sensitive ones (Reports, Purchase prices, Customer personal data, Suppliers and purchasing and Automations – drafts) are unchecked — if Claude should see margins, personal data or propose disabled automation drafts, tick them deliberately. Pick the shops.
- Click Allow. Claude.ai returns to its page and the connector is connected.
- In a conversation click + → Connectors and switch MitoOps on.
What you tick on the consent screen is what applies — and never more than you may see yourself. Whoever has no right to purchase prices in the application cannot pass it on. The token Claude.ai receives carries only the granted scopes.
Another MCP client or AI application over OAuth
Section titled “Another MCP client or AI application over OAuth”You give the application the same /api/mcp address and nothing more — no key. The rest is automatic:
- The application asks us where to send the sign-in (protected resource metadata, RFC 9728).
- Your MitoOps sign-in opens.
- You see the consent screen and pick scopes and shops.
- After approval the connection is ready and the application sees the tools.
An application that picks scopes itself must list them in its request: the consent screen offers only what the application asked for (and what you are entitled to). The interface advertises all scopes including the sensitive ones — in the WWW-Authenticate challenge and in scopes_supported. Sensitive scopes are still never granted on their own: on the consent screen they are marked and unchecked, and the token is narrowed to what you allowed (scope in the token response).
Connecting with an access key
Section titled “Connecting with an access key”The assistant or program needs the /api/mcp address on your domain and an access key with MCP among its interfaces. The exact address is shown on the Settings → API & MCP screen under “Where to plug it in”. A key issued for REST only does not work over MCP and vice versa.
The tool list follows the key or consent scopes: the assistant sees exactly what it was allowed and nothing else. A tool outside the scope does not exist for it.
| MCP tool | Scope | REST | What it returns |
|---|---|---|---|
account_entitlements |
account:read |
GET /account/entitlements |
The client’s plan, features and limits with current usage. |
affiliate_articles_create |
affiliate:write |
— | write: Creating a custom help article in all languages at once (title and body in the given language); HTML is sanitised. |
affiliate_articles_get |
affiliate:read |
GET /affiliate/articles/:key |
One help article with its HTML wording in all or one language; variables not substituted. |
affiliate_articles_list |
affiliate:read |
GET /affiliate/articles |
Help-centre articles of the partner portal: key, default/custom, enabled, order, per-language status. |
affiliate_articles_set_state |
affiliate:write |
— | write: Enabling or disabling a help article for all languages at once; default articles are disabled, never deleted. |
affiliate_articles_update |
affiliate:write |
— | write: Editing a help article in one language (title, slug, body; HTML sanitised) or restoring the default wording; returns unknown variables. |
affiliate_campaigns_create |
affiliate:write |
— | write: Creating a campaign on a shop: name, reward (never invented), attribution window, availability, conversion approval. |
affiliate_campaigns_get |
affiliate:read |
GET /affiliate/campaigns/:campaignId |
One affiliate campaign. |
affiliate_campaigns_list |
affiliate:read |
GET /affiliate/campaigns |
Affiliate campaigns of a shop with reward, availability and counts. |
affiliate_campaigns_update |
affiliate:write |
— | write: Editing a campaign: name, reward, attribution window, availability, approval, enabling/disabling, partner description per language. |
affiliate_code_requests_decide |
affiliate:write |
— | write: Handling a partner code request: approval reserves the code, rejection requires a reason; the partner is e-mailed. |
affiliate_code_requests_list |
affiliate:read |
GET /affiliate/code-requests |
Partner requests for a custom discount code with state and reason; pending first. |
affiliate_conversions_list |
affiliate:read |
GET /affiliate/conversions |
Affiliate conversions of a shop with commission, state and link to the payout. |
affiliate_discount_codes_ensure |
coupons:write |
— | write: Make sure the partner has a discount code on the shop: the coupon is created through canonical coupons (or an existing one is reused) and linked to the partner; the shop note is written automatically. |
affiliate_discount_codes_list |
affiliate:read |
GET /affiliate/discount-codes |
Partner discount codes on a shop with usage count and revenue. |
affiliate_documents_list |
affiliate:read |
GET /affiliate/documents |
Programme documents (terms, agreements): confirmation policy, signed copy, e-mail attachment, versions per language, readiness and acceptance counts. |
affiliate_documents_update |
affiliate:write |
— | write: Programme document policy (who it applies to, when it is confirmed, signed copy, e-mail attachment, enabled); the wording is uploaded in the app. |
affiliate_email_templates_list |
affiliate:read |
GET /affiliate/email-templates |
Partner e-mail templates per language (subject, enabled, body with an event) and automatic attachments of the Account approved e-mail. |
affiliate_email_templates_update |
affiliate:write |
— | write: Editing a partner e-mail template in one language (subject, body) or enabling/disabling an event. |
affiliate_links_generate |
affiliate:read |
GET /affiliate/links/generate |
Tracked affiliate link to the campaign shop home, a product or a category; keeps partner attribution after the click. |
affiliate_partners_get |
affiliate:read |
GET /affiliate/partners/:partnerId |
One programme partner with the campaigns available to them. |
affiliate_partners_list |
affiliate:read |
GET /affiliate/partners |
Programme partners with state, performance and commissions; contacts only with personal data. |
affiliate_partners_set_state |
affiliate:write |
— | write: Partner account decision (approve, reject, suspend, return to waiting); approval sends the e-mail with the agreement. |
affiliate_payouts_list |
affiliate:read |
GET /affiliate/payouts |
Commission payouts to partners with state; without bank and billing data. |
affiliate_portal_get |
affiliate:read |
GET /affiliate/portal |
Public partner portal: addresses per shop, registration openness with reason, custom domains, contact person, appearance and text status per language. |
affiliate_portal_pages_update |
affiliate:write |
— | write: Custom public portal texts in one language (login/register/dashboard pages, privacy notice, programme description); HTML is sanitised. |
affiliate_settings |
affiliate:read |
GET /affiliate/settings |
Affiliate programme settings: commissions, clicks, payout minimum, referrals. |
affiliate_settings_update |
affiliate:write |
— | write: Non-financial programme settings: name, registration, auto-approval, contact person, colours, privacy policy link. |
affiliate_statistics |
affiliate:read |
GET /affiliate/statistics |
Affiliate statistics: daily timeline, attribution sources, partner ranking. |
affiliate_summary |
affiliate:read |
GET /affiliate/summary |
Affiliate programme overview of a shop for a period: clicks, conversions, commissions, partners. |
analytics_channels |
analytics:read |
GET /analytics/channels |
Traffic channels including ChatGPT and other AI sources. |
analytics_order_coverage |
analytics:read |
GET /analytics/order-coverage |
Order coverage by tracking. |
analytics_overview |
analytics:read |
GET /analytics/overview |
Visits, orders, revenue, conversion rate, AOV, share of AI sources. |
analytics_seo |
analytics:read |
GET /analytics/seo |
Search Console by query or page. |
automations_catalog |
automations:read |
GET /automations/catalog |
Automation catalogue: triggers, condition fields, operators, actions, templates and catalogVersion. |
automations_create_draft |
automations:write |
— | write: Creates a DISABLED automation draft. Does not enable or run anything. |
automations_get |
automations:read |
GET /automations/:workflowId |
One automation with DSL and validation result. |
automations_list |
automations:read |
GET /automations |
The client’s automations with state and shop scope. |
automations_runs |
automations:read |
GET /automations/:workflowId/runs |
Run history of one automation. |
automations_templates |
automations:read |
GET /automations/templates |
Ready-made automation templates with DSL. |
automations_update_draft |
automations:write |
— | write: Updates an unpublished automation draft with optimistic concurrency. |
automations_validate_draft |
automations:read |
— | Validates an automation draft without writing. |
claims_get |
claims:read |
GET /claims/:code |
One claim with items, refunds and return shipments. |
claims_list |
claims:read |
GET /claims |
Claims and returns of one shop with links to the order. |
claims_settings |
claims:read |
GET /claims/settings |
Claim processes (types, steps, statuses, deadlines); module settings only with the right to them. |
claims_statistics |
claims:read |
GET /claims/statistics |
Claims and returns statistics for a period: counts, resolution times, types, ratings, reasons. |
content_articles_search |
products:read |
GET /content/articles |
Blog articles and shop content from the canonical mirror by title or text. |
coupons_activation_link |
coupons:read |
GET /coupons/activation-link |
A link that applies an EXISTING coupon in the customer’s cart. Does not create coupons. |
coupons_activation_status |
coupons:read |
GET /coupons/activation-status |
Whether a coupon can be used on the shop via the activation link: coupon mirror + web code status. |
coupons_capabilities |
coupons:read |
GET /coupons/capabilities |
What the shop’s platform can do with coupons. Read before creating. |
coupons_ensure |
coupons:write |
— | write: Make sure the coupon exists on selected shops. With a different discount it is NOT overwritten. |
coupons_get |
coupons:read |
GET /coupons/:code |
One coupon by code. |
coupons_list |
coupons:read |
GET /coupons |
The shop’s discount coupons with discount type and amount, validity and derived state. |
coupons_remove |
coupons:delete |
— | write: Irreversible deletion of a coupon on the selected shop: without confirmation only a preview with dependencies, with confirmation the deletion; a coupon with a live dependency is not deleted. |
coupons_update |
coupons:write |
— | write: Explicit update of an existing coupon including product and category restrictions; preview, then confirmation. |
customers_get |
customers:read |
GET /customers/:customerKey |
One customer from the directory — identity, shops, lifetime and optional period money, broken down per shop. |
customers_list |
customers:read |
GET /customers |
Customer directory: identity (with personal-data masking), shops, language, lifetime counts and revenue by currency; optional purchase-activity filter for a period. |
customers_performance |
reports:read |
GET /customers/performance |
Customers as pseudonyms: orders, revenue, LTV, new and returning. |
credit_notes_search |
invoices:read |
GET /credit-notes |
Search in credit notes. |
invoices_get |
invoices:read |
GET /invoices/:invoiceCode |
One invoice with document items, credit notes, proforma invoices and the order number. |
invoices_search |
invoices:read |
GET /invoices |
Search in invoices. |
inventory_movements |
inventory:read |
GET /inventory/movements |
History of stock movements: when, what, how much, kind, origin, order. |
inventory_product_availability |
inventory:read |
GET /inventory/availability |
Stock level of several items at once. |
inventory_stock |
inventory:read |
GET /inventory/stock |
Stock level of one item including the source of the value. |
orders_get |
orders:read |
GET /orders/:orderCode |
One stored order including items. |
orders_list |
orders:read |
GET /orders |
Stored orders of one shop, newest first. |
categories_list |
products:read |
GET /categories |
Shop categories with product counts. |
products_get |
products:read |
GET /products/:code |
One product by code including category and the price from the card. |
products_search |
products:read |
GET /products |
Product search by name, code, EAN or PLU. |
reports_financial_summary |
reports:read |
GET /reports/financial-summary |
Financial summary of a period; with purchase-prices:read also cost of goods, gross profit and margin. |
sales_order_performance |
reports:read |
GET /sales/order-performance |
Revenue per order with totals for the whole period; with purchase-prices:read also cost, profit and margin. |
sales_product_performance |
reports:read |
GET /sales/product-performance |
Sales per product with totals for the whole period. |
shipping_carriers |
shipping:read |
GET /shipping/carriers |
Connected carriers and profiles, without credentials. |
shipping_shipment_detail |
shipping:read |
GET /shipping/shipments/:shipmentId |
One shipment with all tracking events. |
shipping_shipments |
shipping:read |
GET /shipping/shipments |
Shipments with carrier, country, hand-over and delivery time, paged. |
shipping_stats |
shipping:read |
GET /shipping/stats |
Delivery statistics per carrier: counts, success rate, median and p90 delivery time, countries. |
stores_integration_status |
stores:read |
GET /stores/integration-status |
MitoOps web code status per shop: installed, version, modules, readiness of coupon-from-link. |
stores_list |
stores:read |
GET /stores |
The client’s shops with their code. |
suppliers_get |
purchasing:read |
GET /suppliers/:supplierId |
One supplier with offers and cost components. |
suppliers_list |
purchasing:read |
GET /suppliers |
Suppliers with offers and cost components. |
webhooks_deliveries |
webhooks:read |
GET /webhooks/endpoints/:endpointId/deliveries |
Delivery log of one endpoint without bodies. |
webhooks_endpoint |
webhooks:read |
GET /webhooks/endpoints/:endpointId |
One webhook endpoint with the number of pending deliveries. |
webhooks_endpoints |
webhooks:read |
GET /webhooks/endpoints |
The client’s webhook endpoints without secrets and the queue state. |
webhooks_events |
webhooks:read |
GET /webhooks/events |
The catalogue of outbound webhook events, envelope and signature. |
The customer’s name, e-mail, phone and street appear in orders_list, orders_get, claims_list and claims_get only with the personal-data:read scope; without it the response carries the country and city. The same applies to supplier and affiliate partner contacts (affiliate_partners_*). The scope has no tool of its own.
In the customer directory (customers_list, customers_get) the same scope governs the name, company, e-mail, phone and marketing gender; without it what remains is the pseudonym, shops, country, language, counts and dates. Revenue and LTV sit behind reports:read on top of that. Marketing gender is an inference from the first name (genderSource: "name_inference"), not something the customer stated — and an assistant should present it that way. Bank and tax data of partners are never returned.
Every tool has a REST counterpart over the same capability. The envelopes differ, the business data is identical. Period, pagination and the meaning of the financial fields are described in the REST interface.
Summary tools (shipping_stats, analytics_*, reports_financial_summary) return finished figures from the application — the assistant does not have to download thousands of records and compute them itself. Raw listings (shipping_shipments, orders_list) remain for drill-down.
What you can ask
Section titled “What you can ask”Once connected, Claude.ai answers from MitoOps data, for example:
- “What was the carrier split in August?” —
shipping_stats - “What was the median delivery time of DHL and GLS?” and “How many were undelivered or returned?” —
shipping_stats - “Which countries did we ship to via DHL?” —
shipping_stats(fieldcountries) - “What were revenue and conversion rate in August?” —
analytics_overvieworreports_financial_summary - “How many orders and how much revenue came from ChatGPT?” —
analytics_channels - “Which queries had the highest CTR?” —
analytics_seo - “What is the margin of product X last month?” —
sales_product_performance(withpurchase-prices:read)
Reading and narrow writes: automation draft, coupon, affiliate programme
Section titled “Reading and narrow writes: automation draft, coupon, affiliate programme”Operational data (orders, stock, products, documents, shipments) is read-only over MCP. There are three kinds of writes, each behind its own sensitive scope.
Automation draft — with the automations:write scope it is a disabled draft: with the automations:write scope the assistant can design a rule from the catalogue (automations_catalog) and save it as a draft, or edit a draft nobody has published yet. The draft appears in Automations like any other work in progress — only you can enable, publish or run it in the application. The assistant cannot change a published automation (it creates a new draft instead).
The automations:write scope is sensitive: it is not pre-checked on the consent screen, it is offered only to a person allowed to edit automations, existing connections do not inherit it and a token refresh cannot widen it. Orders, products, stock, documents, refunds, claims and shipments cannot be changed over MCP, and webhook endpoints are read-only over MCP. Credentials for carriers, the shop or analytics cannot be read over MCP.
Discount coupon — with the coupons:write scope the assistant creates a coupon from the parameters you give it (coupons_ensure, including a partner coupon via affiliate_discount_codes_ensure) and explicitly updates an existing one (coupons_update, preview and confirmation); deletion has its own coupons:delete scope and a coupon with a live dependency is not deleted.
Affiliate programme management — with the affiliate:write scope the assistant decides on a partner account (affiliate_partners_set_state: approve, reject, suspend; the partner receives an e-mail, with the agreement PDF according to the document policy), handles a custom code request (affiliate_code_requests_decide), updates non-financial programme settings (affiliate_settings_update: name, registration, contact person, colours), portal texts in one language (affiliate_portal_pages_update), help articles (affiliate_articles_create, affiliate_articles_update including restoring the default wording, affiliate_articles_set_state; no deletion from outside), e-mail templates (affiliate_email_templates_update), campaigns (affiliate_campaigns_create, affiliate_campaigns_update) and document policy (affiliate_documents_update). Commission approval, payouts, the commission base and document file upload do not exist over MCP — they stay in the app.
Tools carry annotations per the protocol revision (readOnlyHint, destructiveHint, idempotentHint); automations_create_draft is idempotent through clientRequestId, automations_update_draft requires expectedVersion and returns CATALOG_CHANGED when the catalogue changed.
Protocol revisions
Section titled “Protocol revisions”The server speaks revision 2026-07-28 as well as older ones (2025-11-25, 2025-06-18, 2025-03-26). The client chooses by what it sends, so older client libraries connect without modification.
The newer revision has no initial handshake and no session: every request carries its own version and the mandatory headers MCP-Protocol-Version, Mcp-Method and, for a tool call, Mcp-Name. If a header disagrees with the body the response is 400 — routing by headers while executing by the body would mean two sources of truth about the same call.