Skip to main content
Glama
retailcrm-mcp

retailcrm-mcp

by veterinar

retailcrm-mcp

Production-grade MCP server for RetailCRM e-commerce CRM. 44 tools + 2 prompt skills for managing orders, customers, products, inventory, payments, tasks, references, and analytics via API v5.

API traffic is transported by the official retailcrm/api-client-php client, pinned to 6.15.32, invoked from Node through a PHP bridge (bin/retailcrm-api.php). The server ships as a self-contained Docker image — no host PHP or Composer required.

Forked from theYahia/retailcrm-mcp (MIT).

Output is token-efficient by default

Read tools return a compact, shaped summary of only the fields an agent needs — not the full RetailCRM payload. Control verbosity per call:

Param

Effect

(default)

detail:"summary" — essential fields + a pagination block

detail:"full"

All shaped fields (line items, delivery, payments, address…)

raw:true

The untouched RetailCRM response (for debugging)

⚠️ v3 was a breaking change vs v2: default output is the shaped summary instead of raw JSON. Pass raw:true to restore the old payload.

Related MCP server: Method CRM MCP Server

Tools (44)

Orders

Tool

Description

list_orders

List orders by status, customer, number, date range

get_order

Get one order by ID or externalId

create_order

Create an order; link an existing customer (customer_id/customer_external_id) or create one inline

update_order

Update status, customer, delivery, comments

orders_history

Order change history (incremental sync). Default: safe PII-free projection (status, payments and fullPaidAt as full_paid_at old→new changes); raw:true for the untouched payload. Cursor calls (filter_since_id) never send page — the API rejects sinceId+page since 2023-05-15

Customers

Tool

Description

list_customers

Search customers by name, email, phone, date

get_customer

Get one customer by ID or externalId

create_customer

Create a customer

update_customer

Edit an existing customer

merge_customers

Merge duplicates (destructive)

customers_history

Customer change log (growth/churn, incremental sync)

Products & inventory

Tool

Description

list_products

Catalog products by name, group, active, price

list_product_groups

Product category tree

store_inventories

Stock levels & cost prices per offer/warehouse

Payments

Tool

Description

order_payment_create

Record a payment on an order

order_payment_edit

Edit a payment

order_payment_delete

Delete a payment (destructive)

Notes & tasks

Tool

Description

customer_notes_list / customer_notes_create / customer_notes_delete

Free-text customer notes

tasks_list / tasks_create / tasks_edit

Follow-up tasks/reminders

Marketing & finance

Tool

Description

list_segments

Customer segments (RFM/marketing cohorts)

list_costs / create_cost

Expense records for margin analytics

Files

Tool

Description

files_list / files_get / files_upload

Attach & retrieve files (raw octet-stream upload)

References

Tool

Description

list_statuses / list_delivery_types / list_payment_types / list_stores

Order/delivery/payment/store reference data

list_sites

Sites the API key can act on (fill the site param)

list_countries / list_order_types / list_order_methods

Address & order reference data

Analytics

Tool

Description

get_orders_summary

Period-scoped order stats: exact count + revenue, AOV, status distribution

get_customers_summary

New-customer count for a date range

Analytics: PII-free SEO-SXO surface

Read-only, pagination-complete analytics that a Yandex Metrica layer can join on a pseudonymous key — no customer identity persisted or returned. Criteria: docs/criteria/retailcrm-analytics-sxo-v1.md.

Tool

Description

retailcrm_attribution_fields

Search ORDER custom-field metadata (code/name/type; request scoped with filter[entity]=order) for attribution candidates; never reads field values

retailcrm_orders_analytics

PII-free order analytics for a date window (date_basis: created_at): full pagination with explicit max_pages/max_orders bounds, per-order safe fields + HMAC join key. Each order carries the canonical full_paid_at (from order.fullPaidAt; paid_at is the byte-equal compatibility alias), payment_provider (SBER/OZON/CASH/OTHER/UNKNOWN, evidence-only) proven only by completed payments mapped via RETAILCRM_ANALYTICS_PAYMENT_PROVIDER_MAP, plus sber_paid_amount_rub (the safe crm_paid_amount only when the proven provider is SBER, else null) and delivery_income_rub (the customer-paid delivery.cost only when the safe delivery projection accepted it, else null)

retailcrm_paid_orders

Same projection restricted to orders proven fully paid by non-empty order.fullPaidAt; the window filters on full-paid time (filter[fullPaidAtFrom]/[To], date_basis: full_paid_at) and fails closed if the provider returns an order without that evidence. Each order exposes the canonical full_paid_at (with paid_at as the byte-equal compatibility alias), evidence-only payment_provider, sber_paid_amount_rub (safe crm_paid_amount only when the provider is proven SBER) and delivery_income_rub (customer-paid delivery.cost only when safely accepted)

retailcrm_order_attribution

PII-free attribution for one order by id/externalId

retailcrm_order_history_analytics

Incremental change feed via the official /orders/history sinceId cursor (never sends page — the API rejects sinceId+page since 2023-05-15); returns next_since_id for resumption; totalPageCount>1 signals another cursor fetch, <=1 completes

Projection is allowlist-only: ids, timestamps, status, order method, site, total/currency, native source/medium/campaign, retailcrm_client_id (native label — never represented as Yandex client_id), configured attribution tokens, safe item fields, authoritative sales_channel and the HMAC-SHA256 join key. sales_channel is read only from the order's own customFields.sales_channel; missing historical, empty, malformed or unsupported values are UNKNOWN. Delivery, order method, site, source and attribution never determine the sales channel. The legacy channel field remains compatibility-only and is derived from sales_channel without fallback. payment_evidence separates order-level CRM proof from payment-amount evidence: crm_fully_paid, the canonical full_paid_at and its byte-equal compatibility alias paid_at come only from non-empty order.fullPaidAt (payment/order statuses can never populate them); paymentComplete=true selects individual numeric payment amounts only for crm_paid_amount and amount_matches; payment_provider is evidence-only, proven solely by completed payments with exactly mapped types. sber_paid_amount_rub reuses that safe crm_paid_amount only when the proven provider is SBER (otherwise null; the acquiring fee is never calculated here), and delivery_income_rub is the customer-paid delivery.cost copied only when the safe delivery projection accepted a finite non-negative number (never derived from totalSumm, netCost, delivery type or defaults). The RetailCRM-only states are CRM_PAID, PARTIAL and UNKNOWN; FINANCE_CONFIRMED requires a separate downstream settlement join and is not emitted here. Item revenue sums every prices[] tranche (price*quantity) when the tranches are numerically complete, otherwise initialPrice * quantity - discountTotal, where discountTotal is the total discount for the line; vat_rate is the provider's string verbatim; item SKU is offer.externalId → xmlId → article. History old/new values are exposed only for status, payments and fullPaidAt as full_paid_at; a history record without an orderExternalId gets join_key: null with join_key_omitted_reason: "no_order_external_id" (never a CRM-id HMAC). max_orders/max_records are page-aligned soft stops (may overshoot by at most one 100-record page), stated in each output's bounds block. Names, phones, emails, addresses, comments, marking codes, user ids and arbitrary custom fields are never emitted. All order analytics tools fail closed when RETAILCRM_ANALYTICS_HMAC_SECRET is absent or shorter than 32 characters.

Prompt Skills (2)

Skill

Description

new-orders

Quick daily overview of today's orders

customer-search

Find a customer by name, email, or phone

Setup

  1. In RetailCRM, go to Settings > Integration > API keys.

  2. Create an API key with the required permissions (orders, customers, store, references). For a multi-site key, pass the site code on create/edit tools (see list_sites).

  3. Note your domain (the yourstore part of yourstore.retailcrm.ru).

Environment Variables

Secrets are provided via environment variables only — never on the command line, in config files, or in logs.

Variable

Required

Description

RETAILCRM_DOMAIN

Yes

Your RetailCRM domain (e.g. yourstore.retailcrm.ru)

RETAILCRM_API_KEY

Yes

API key (sent via the X-API-KEY header by the PHP client)

RETAILCRM_READONLY

No

1 to expose only read tools (hide create/update/merge/delete)

RETAILCRM_RATE_LIMIT

No

Client-side requests/second cap (RetailCRM allows ~10/s)

RETAILCRM_PHP_BIN

No

PHP executable for the local (non-Docker) path (default php)

RETAILCRM_PHP_BRIDGE

No

Path to bin/retailcrm-api.php (set automatically in Docker)

PORT / HOST

No

HTTP server bind (default 3000 / 127.0.0.1, --http mode only)

RETAILCRM_HTTP_ALLOWED_HOSTS

No

Comma-separated allowed Host values for DNS-rebinding protection

RETAILCRM_DNS_PROTECTION

No

off to disable DNS-rebinding protection (HTTP mode)

RETAILCRM_ANALYTICS_HMAC_SECRET

For analytics

HMAC-SHA256 key for pseudonymous order join keys (>= 32 chars; order analytics fail closed without it)

RETAILCRM_ANALYTICS_ATTRIBUTION

No

JSON map of canonical key (client_id, yclid, utm_source, utm_medium, utm_campaign, utm_content, utm_term) to exact order custom-field code. No defaults — use retailcrm_attribution_fields to discover codes

RETAILCRM_ANALYTICS_ECONOMICS

No

JSON map of outside_mkad_surcharge, commission_total, return_total to exact numeric order custom-field codes. Missing or invalid values remain null; no field code or amount is guessed

RETAILCRM_ANALYTICS_PAYMENT_PROVIDER_MAP

No

JSON map of exact RetailCRM payment type codes to a closed provider set (SBER, OZON, CASH, OTHER). Absent is valid (every order gets payment_provider: UNKNOWN); malformed JSON/container/keys/values fail before any API call. A provider is proven only when ALL completed payments of an order have mapped types resolving to one provider — no status/site/channel/delivery fallback, and raw payment types are never emitted

RETAILCRM_URL is still accepted as a fallback for RETAILCRM_DOMAIN.

Build the self-contained image (Node + PHP CLI/cURL + compiled server + PHP bridge + Composer production dependencies — official retailcrm/api-client-php 6.15.32):

docker build -t retailcrm-mcp:3.1.0 .

Run over stdio:

docker run --rm -i \
  -e RETAILCRM_DOMAIN=yourstore.retailcrm.ru \
  -e RETAILCRM_API_KEY=your-api-key \
  retailcrm-mcp:3.1.0

Run the Streamable HTTP server instead by appending --http:

docker run --rm -p 127.0.0.1:3000:3000 \
  -e RETAILCRM_DOMAIN=yourstore.retailcrm.ru \
  -e RETAILCRM_API_KEY=your-api-key \
  -e HOST=0.0.0.0 \
  retailcrm-mcp:3.1.0 --http

Usage with Claude Desktop / MCP clients

{
  "mcpServers": {
    "retailcrm": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i", "--init",
        "-e", "RETAILCRM_DOMAIN",
        "-e", "RETAILCRM_API_KEY",
        "retailcrm-mcp:3.1.0"
      ],
      "env": {
        "RETAILCRM_DOMAIN": "yourstore.retailcrm.ru",
        "RETAILCRM_API_KEY": "your-api-key"
      }
    }
  }
}

Optional: local Node + PHP + Composer

If you prefer not to use Docker, run the same stack locally:

# 1. Node dependencies + compile
npm install
npm run build

# 2. PHP dependencies (Composer >= 2; plugins and scripts disabled)
composer install --no-dev --no-interaction --no-progress --no-scripts --no-plugins --optimize-autoloader

# 3. Run (stdio)
RETAILCRM_DOMAIN=yourstore.retailcrm.ru \
RETAILCRM_API_KEY=your-api-key \
node dist/index.js

# Or the HTTP server
RETAILCRM_DOMAIN=yourstore.retailcrm.ru \
RETAILCRM_API_KEY=your-api-key \
node dist/index.js --http

Requires Node >= 18 and PHP >= 8.1 with the cURL, JSON, mbstring, and openssl extensions.

Architecture & the raw-upload exception

  • All normal RetailCRM traffic (GET and form POST) goes through the official retailcrm/api-client-php 6.15.32 client (SimpleClientFactory::createClient + CustomMethods/CustomApiMethod), executed inside bin/retailcrm-api.php.

  • The Node client (src/client.ts) talks to the bridge over JSON on stdin/stdout with a versioned, fail-closed protocol: malformed, empty, or non-JSON bridge output is always an error, never success.

  • files_upload is the one documented compatibility exception. The official v6.15.32 FilesUploadRequest does not preserve this MCP's ?filename= query parameter and caller MIME type, so the bridge performs that single call with PHP cURL — same normalized origin, X-API-KEY header, 15-second timeout, and bounded error handling. Every other tool uses the official client.

  • Retry policy is unchanged: 3 attempts, 429 always retried, timeout/5xx retried for GETs only (never for ambiguous POSTs), optional client-side rate gate.

Demo Prompts

1. Daily order overview: "Show me all orders created today with status 'new'. Summarize the total count and revenue."

2. Customer lookup and order history: "Find the customer with email anna@example.com. Show their full profile and recent orders."

3. Stock check: "Is the product with externalId SKU-42 in stock, and in which warehouse?"

Webhooks / Triggers

RetailCRM does not support API-created webhooks. Use Triggers in the admin panel (Settings > Triggers) to send HTTP requests to external endpoints on order/customer events.

Error Handling

  • Rate limits / 5xx: automatic retry with exponential backoff + jitter (up to 3 attempts).

  • API errors: RetailCRM error details are parsed and returned to the model as a tool result with isError: true, so the agent can self-correct (e.g. retry with by:"externalId").

  • Timeouts: 15-second whole-call timeout, enforced by terminating the bridge process.

Development

npm install
npm test          # vitest (mock-based; no live API key needed)
npm run lint      # eslint
npm run typecheck # tsc --noEmit
npm run dev       # stdio dev mode (tsx)
npm run build     # clean + compile to dist/

License

MIT — upstream © Yahia (theYahia/retailcrm-mcp); retailcrm/api-client-php is MIT © RetailCRM.

Available Tools

39 tools
create_costA

Create an expense record, optionally attributed to an order. Returns {success, id}.

Inputs: summ (required), cost_item (required), date_from (required), site, +3 more.

create_customerA

Create a customer with name, contacts, address, optional externalId. Returns {success, id}.

Inputs: first_name (required), site, email, phones, +6 more.

create_orderA

Create an order with line items and delivery. Link an existing customer via customer_id/customer_external_id, or pass first_name (+phone/email) to create one inline. Returns {success, id, order?}.

Inputs: items (required), site, email, phone, +9 more.

customer_notes_createA

Add a note to a customer (by id or externalId). Returns {success, id}.

Inputs: text (required), site, manager_id, customer_id, +1 more.

customer_notes_deleteA
Destructive

Delete a customer note by id. Returns {success}.

Inputs: id (required).

customer_notes_listA
Read-only

List free-text notes attached to customers. Returns {notes[], pagination}.

Inputs: page, limit, filter_customer_id, filter_customer_external_id.

customers_historyA
Read-only

Customer field-change log for growth/churn signals and incremental sync. Returns {history[], pagination}.

Inputs: raw, page, limit, filter_date_to, +2 more.

files_getA
Read-only

Get a file's metadata by id. Returns {file}.

Inputs: id (required).

files_listA
Read-only

List files attached to orders/customers. Returns {files[], pagination}.

Inputs: page, limit, filter_filename, filter_order_id, +1 more.

files_uploadA

Upload a file (UTF-8 text or base64 binary). Returns {success, file}.

Inputs: content (required), filename (required), base64, content_type.

get_customerA
Read-only

Get a single customer by id or externalId. Returns a shaped customer; detail:'full' adds address and contact details.

Inputs: id (required), by, raw, detail.

get_customers_summaryA
Read-only

Period-scoped new-customer count for a date range. Returns {period, newCustomers}.

Inputs: date_to (required), date_from (required).

get_orderA
Read-only

Get a single order by RetailCRM id or externalId. Returns a shaped order; detail:'full' adds items, delivery, payments, comments.

Inputs: id (required), by, raw, detail.

get_orders_summaryA
Read-only

Period-scoped order summary: exact totalCount for the date range plus revenue, average order value, and status distribution aggregated over up to max_pages×100 orders (partial:true if the window exceeds that).

Inputs: date_to (required), date_from (required), max_pages, filter_status.

list_costsA
Read-only

List expense records (for margin/profit analytics) by date and cost group. Returns {costs[], pagination}.

Inputs: page, limit, filter_date_to, filter_date_from, +1 more.

list_countriesB
Read-only

Valid country ISO codes for addresses/delivery.

Inputs: raw.

list_customersA
Read-only

List/search customers by name, email, phone, created-date. Returns (summary): pagination + array of {id, name, email, phone, ordersCount, totalSpent}. detail:'full' adds address/externalId/all phones.

Inputs: raw, page, limit, detail, +5 more.

list_delivery_typesA
Read-only

All delivery types with codes, names, default costs.

Inputs: raw.

list_order_methodsB
Read-only

All order methods (acquisition channels).

Inputs: raw.

list_ordersA
Read-only

List orders with filters by status, customer name, number, and created-date range. Returns (summary): pagination + array of {id, number, status, total, customer, phone, itemCount, createdAt}. Use detail:'full' for line items/delivery/payments, raw:true for the untouched payload.

Inputs: raw, page, limit, detail, +5 more.

list_order_typesA
Read-only

All order types (codes/names) — valid values for create_order's order_type.

Inputs: raw.

list_payment_typesB
Read-only

All payment types with codes and names.

Inputs: raw.

list_product_groupsA
Read-only

List product groups (category tree). Returns {productGroup[], pagination}.

Inputs: page, limit, filter_active, filter_parent_group.

list_productsA
Read-only

List catalog products with filters by name, active, group, price range. Returns pagination + array of {id, name, article, active, url, groups, offers}.

Inputs: raw, page, limit, filter_name, +4 more.

list_segmentsA
Read-only

List customer segments (RFM/marketing cohorts). Returns {segments[], pagination}.

Inputs: page, limit, filter_type, filter_active.

list_sitesA
Read-only

All sites/stores the API key can act on — use the returned code as the site param on multi-site create/edit.

Inputs: raw.

list_statusesA
Read-only

All order statuses (codes, names, groups, ordering). Call before filtering/updating orders by status.

Inputs: raw.

list_storesB
Read-only

All warehouses/stores (codes, names, types).

Inputs: raw.

merge_customersA
Destructive

Merge duplicate customers into a target; merged records are DELETED. Returns {success}.

Inputs: result_customer_id (required), merged_customer_ids (required).

order_payment_createA

Record a payment against an order (amount, type, status, paid_at). Returns {success, id}.

Inputs: type (required), amount (required), site, status, +3 more.

order_payment_deleteA
Destructive

Delete an order payment by id. Returns {success}.

Inputs: id (required).

order_payment_editA

Edit an existing order payment (amount/status/paid_at). Returns {success}.

Inputs: id (required), by, site, amount, +2 more.

orders_historyA
Read-only

Order change history incl. status transitions; supports incremental sync via filter_since_id and a date window. Returns {history[], pagination}.

Inputs: raw, page, limit, filter_date_to, +3 more.

store_inventoriesA
Read-only

Stock levels (and cost prices) per offer/warehouse. Use details:true for the per-store breakdown. Returns {offers[], pagination}.

Inputs: page, site, limit, details, +2 more.

tasks_createA

Create a task (text, due datetime, performer, linked order/customer). Returns {success, id}.

Inputs: text (required), site, datetime, order_id, +3 more.

tasks_editA

Edit a task or mark it complete. Returns {success}.

Inputs: id (required), site, text, complete, +3 more.

tasks_listA
Read-only

List follow-up tasks/reminders, filterable by status/performer/customer. Returns {tasks[], pagination}.

Inputs: page, limit, filter_status, filter_customer, +1 more.

update_customerA

Edit an existing customer (name, email, phones, address) by id or externalId. Only the fields you pass are sent. Returns {success}.

Inputs: id (required), by, site, email, +7 more.

update_orderA

Update an order (status, customer, delivery, comments). Only the fields you pass are sent. Returns {success}.

Inputs: id (required), by, site, email, +11 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 39 tools

    Disambiguation5/5

    Each tool targets a distinct resource-action pair. Even with many list_* tools, the resources (orders, customers, products, statuses, etc.) are clearly different, and descriptions prevent confusion.

    Naming Consistency2/5

    Naming is inconsistent: verb-first ('list_orders', 'create_order') for core entities vs noun-first ('tasks_list', 'order_payment_create') for sub-entities. Also 'store_inventories' lacks a verb, breaking the pattern.

    Tool Count2/5

    At 39 tools, this is far beyond the typical well-scoped range. While the CRM domain is broad, the tool surface would benefit from consolidation, e.g., a generic reference-data lister or grouping sub-resources.

    Completeness3/5

    Core order/customer workflows are well covered (CRUD, history, payments, notes). However, product management is missing (only list), and costs/tasks/files lack full CRUD (e.g., no product create/update, no cost edit/delete).

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      ozon-mcp is a knowledge-rich MCP server that turns the entire Ozon seller toolkit into 15 high-leverage tools. AI agents (Claude, Cursor, Cline, Continue, Goose, Zed, …) can search the API in Russian or English, drill into any of 466 methods with a fully-resolved JSON Schema, and execute calls with built-in safety guards. Subscription- aware, automatic pagination over all 4 cursor styles, retry/ba
      15
      26
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      A production-ready MCP server for Method CRM API integration. It enables LLMs to interact with Method CRM data through tools for tables, files, users, events, and API key management.
      3
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      Self-hosted MCP server that connects AI assistants to Kommo CRM (API v4), enabling real-time CRM actions such as creating/managing leads, tasks, notes, and more through 29 tools.
      29
      1
      MIT
    • A
      license
      B
      quality
      B
      maintenance
      Production-grade MCP server for RetailCRM e-commerce CRM. Provides 39 tools and 2 prompt skills to manage orders, customers, products, inventory, payments, tasks, references, and analytics via API v5.
      39
      42 npm
      2
      MIT