EasyCRM MCP
An MCP server for one Shopify store and one Horoshop store. Tools are grouped by platform and resource so each action has a clear destination and input contract.
The server runs locally and sends requests directly to each configured platform. Credentials stay in your MCP client configuration on your machine.
Quick start
https://github.com/user-attachments/assets/ab10078a-c557-4f72-b37a-1958c3991029
npx -y easycrm-mcp init
To run the setup wizard directly from a repository checkout, use npm ci and npm run dev -- init.
The wizard lets you configure Shopify, Horoshop, or both. It verifies each connection and registers the server in the client you pick:
- Claude Code
- Codex CLI
- Gemini CLI
- Claude Desktop
- Cursor
- Windsurf
- VS Code (Copilot)
Pick "Other" to print a config entry for any other MCP client.
Store credentials
Shopify
You need a store on a plan with Admin API access and one of:
Option A: Dev Dashboard app (for stores in your own Shopify organization)
Go to dev.shopify.com/dashboard and create an app for a store in your organization. Shopify limits client credentials to stores in your own organization.
Grant only the scopes needed for the tools you plan to use:
Resource Read Write Themes read_themeswrite_themesShopify Files for theme media read_fileswrite_filesPages read_contentwrite_contentMenus read_online_store_navigationwrite_online_store_navigationProducts and variants read_productswrite_productsInventory read_inventory,read_locationswrite_inventoryCustomers read_customerswrite_customersOrders read_orderswrite_ordersFulfillment orders Matching assigned, merchant-managed, or third-party fulfillment read scope Matching fulfillment write scope Discounts read_discountswrite_discountsNative sales reports read_reportsNone Shopify customer data also requires protected customer data approval. Orders older than 60 days normally require
read_all_orders. Some actions require additional staff permissions or an offline token. The individual tool descriptions state these cases.The native Shopify sales report requires Level 2 protected customer data access, as documented forshopifyqlQuery.Copy the Client ID and Client Secret from the app's settings.
Option B: existing admin access token
Use an existing shpat_… token from an admin-created custom app. Shopify no longer allows creating new admin-created custom apps.
Editing theme files requires Shopify's write_themes exemption in addition to the API scope. See Shopify's themeFilesUpsert requirements.
Horoshop
Create a dedicated API admin login in the Horoshop admin panel under Settings > Admins. Configure the store's HTTPS origin, login, and password. Horoshop issues an API token valid for 600 seconds; this server renews it automatically. See the official Horoshop API documentation and authentication details.
Manual configuration
If you skip the wizard, add this to your MCP client's config:
{
"easycrm": {
"command": "npx",
"args": ["-y", "easycrm-mcp"],
"env": {
"SHOPIFY_STORE_DOMAIN": "your-store.myshopify.com",
"SHOPIFY_CLIENT_ID": "…",
"SHOPIFY_CLIENT_SECRET": "…",
"HOROSHOP_STORE_URL": "https://shop.example.com",
"HOROSHOP_LOGIN": "your_api_login",
"HOROSHOP_PASSWORD": "…"
}
}
}
You can configure either platform by omitting the other platform's variables. For Shopify, you can use an existing access token instead of client credentials by setting SHOPIFY_ADMIN_ACCESS_TOKEN.
Tools
Shopify
| Tool | What it does |
|---|---|
shopify_get_info |
Read Shopify store name, domain, plan, currency |
shopify_theme_list |
List Shopify themes |
shopify_theme_active |
Identify the current live MAIN theme |
shopify_theme_import_draft |
Import a theme ZIP as unpublished |
shopify_theme_duplicate_draft |
Copy an existing theme into an unpublished draft |
shopify_theme_publish |
Publish a theme after confirming the current MAIN theme and user approval |
shopify_theme_read_file |
Read a Shopify theme file |
shopify_theme_update_file |
Create or update a theme file, with a live-theme guard |
shopify_theme_media_slots |
Find image and video picker settings in a theme JSON template, section group, or global settings |
shopify_theme_media_upload_local |
Upload a local image or MP4 video into Shopify Files |
shopify_theme_media_file_status |
Check media processing and get its theme reference |
shopify_theme_media_set |
Fill or replace one selected theme media setting with a ready file |
shopify_page_list |
List Shopify pages |
shopify_page_create |
Create a Shopify page |
shopify_page_update |
Update a Shopify page |
shopify_menu_list |
List Shopify menus |
shopify_menu_update |
Replace a Shopify menu |
shopify_product_list/get/create/update/delete |
Manage core product fields |
shopify_product_create_draft_with_images |
Create an unpublished product and submit image URLs, optionally setting its first price |
shopify_product_image_add |
Add images to an existing product |
shopify_product_image_add_local |
Upload a local image and attach it to an existing product |
shopify_product_media_list |
Check image processing status and URLs |
shopify_product_variant_list/update_price |
Read variants and change a price |
shopify_inventory_location_list |
Find inventory locations |
shopify_product_variant_inventory |
Read available quantity by location |
shopify_inventory_set_available |
Set available quantity with a comparison value and idempotency key |
shopify_customer_list/get/create/update/delete |
Manage customer profiles |
shopify_customer_purchase_history |
Read a customer's orders and purchased items by customer ID |
shopify_order_list/get/create/update/delete/cancel |
Manage orders within Shopify's operation rules |
shopify_order_line_items |
Page through purchased items in one order |
shopify_order_fulfillment_orders |
Find fulfillable units for an order |
shopify_fulfillment_create |
Fulfill one entire fulfillment order |
shopify_order_summary |
Compute a bounded order summary from accessible orders |
shopify_sales_report |
Read native Shopify Analytics sales metrics by day, month, or total |
shopify_discount_code_list/create/create_fixed/update/delete |
Manage basic code discounts by percentage or fixed amount |
shopify_discount_automatic_list/create/update/delete |
Manage basic automatic discounts |
Horoshop
| Tool | What it does |
|---|---|
horoshop_category_list |
Read child categories under a parent |
horoshop_product_list |
Read products, optionally filtered by article (SKU) |
horoshop_product_reviews |
Read public product reviews and load more batches when available |
horoshop_product_create |
Create a product in a selected category with optional images |
horoshop_product_update |
Update an existing product's price, text, visibility, warehouse stock, or images |
horoshop_customer_upsert |
Create or update one customer by email |
horoshop_customer_purchase_history |
Find orders and purchased products by delivery email |
horoshop_order_list |
Read paged orders with optional date and status filters |
horoshop_order_statuses |
Read configured order status IDs |
horoshop_order_update |
Set one order's status or payment flag |
horoshop_order_summary |
Compute bounded counts and totals from orders in a date range |
Each tool is tied to one configured platform. Horoshop product creation accepts image URLs for a variant gallery or a shared gallery. Image updates require an explicit append or replace mode; replace removes the existing images in that gallery. Horoshop fetches images from the supplied URLs, with a 5 MB limit for each source image. The product list supports offset and limit for paging, with a maximum of 500 products per request per the Horoshop export API. Horoshop category export requires platform version 4 or later.
horoshop_product_reviews accepts a product URL or path on the configured store. It reads public schema.org/Review markup, including reviews without star ratings. It tries a plain HTTP request first. For a JavaScript challenge or additional review batches, it opens a temporary headless Chrome session and closes it after the read. Chrome must be installed locally; no browser is downloaded with this package. Set HOROSHOP_BROWSER_EXECUTABLE_PATH if Chrome is installed in a nonstandard location. maxReviews defaults to 20 and is capped at 100. totalCount reflects the page's review count, and complete: false means more reviews may exist. The tool does not read private or unpublished reviews.
Before editing theme files, call shopify_theme_active or shopify_theme_list. The update tool checks the observed role again. Editing the live MAIN theme requires explicit user approval and confirmLiveTheme: true; publishing requires approval, confirmPublish: true, and the expected current MAIN theme ID. Draft themes can be edited without changing the live storefront. Shopify requires a theme API exemption for theme mutations.
To change a theme banner image or video, inspect its settings with shopify_theme_media_slots using the relevant template path, for example templates/index.json. The result identifies section, block, and setting IDs, including empty media pickers. Upload a local file with shopify_theme_media_upload_local, wait for shopify_theme_media_file_status to report READY, then call shopify_theme_media_set with the returned file ID and the slot's observed value. The setter checks the theme schema and current value again, and changes only that setting. Images may be PNG, JPEG, WebP, or GIF up to 20 MB. Video upload currently supports MP4 up to 1 GB and streams the local file. The file path is read on the machine running the MCP server. video_url settings for YouTube or Vimeo are separate from Shopify-hosted video pickers and are not handled by this flow. A concurrent Theme Editor save during the final theme file write can still overwrite changes because Shopify does not offer an atomic compare-and-swap for theme JSON files.
Shopify product images can be submitted from public HTTPS URLs or local files. The local-image tool accepts an absolute path on the MCP server machine and uploads one PNG, JPEG, WebP, or GIF up to 20 MB through Shopify staging before attaching it to the product. Shopify processes images asynchronously, so use shopify_product_media_list to check readiness. Creating a draft with an initial price uses a second mutation for the default variant. If that step fails, the tool returns the created product ID and marks the partial result as an error.
Analytics
shopify_sales_reportreads native Shopify Analytics through ShopifyQL. Select a date range, total/daily/monthly interval, and metrics such as sales, orders, discounts, and average order value. This requiresread_reportsand Level 2 protected customer data access.shopify_order_summarycalculates order counts and current order totals from accessible orders. It reportspaginationCompleteand a cursor when it stops before the last page.horoshop_order_summarycalculates order counts, paid counts, totals by currency, and breakdowns by status and UTM source from the Horoshop orders API. Currency totals are exact decimal strings, for example"0.3". It scans at most 5,000 orders and reportscomplete: falseif more may exist.
The two order summaries are calculated from API orders, not native analytics reports or settled payment revenue. Horoshop total_sum includes discounts and excludes shipping. The server does not currently expose traffic, sessions, or conversion funnel analytics for Horoshop.
Purchase history
Both purchase history tools read store data through the configured API connection. Shopify searches orders by customer ID, newest first, and returns an order cursor for the next page. Each order includes up to 20 line items; when itemsComplete is false, pass nextItemsCursor and the order ID to shopify_order_line_items to read more. Shopify normally limits order access to the most recent 60 days unless the app has read_all_orders.
Horoshop has no documented customer filter for orders/get, so horoshop_customer_purchase_history scans up to maxPages pages of 100 orders, matching delivery_email exactly without regard to letter case. Use from and to to narrow the search. If complete is false, pass nextOffset as offset in another call to continue. An empty result with complete: false does not establish that the customer has no earlier purchases.
The current tools do not cover every action in either admin. In particular, Shopify refunds, partial fulfillment, edits to line items, advanced discount types, and Horoshop customer deletion or order creation/deletion need separate workflows and API verification. Shopify cancellation returns a job ID because processing is asynchronous. See the architecture notes for the extension plan.
Moving from the Shopify-only package
The previously published shopify-store-builder-mcp package remains available. To use this package, replace the npm command with easycrm-mcp, use the new easycrm MCP entry, and update tool names to their shopify_ versions. Horoshop variables can then be added to the same entry.
Development
npm install
npm run dev # run from source
npm run build # compile to dist/
npm test
npm audit
License
ISC