ecommerce-mcp-automation
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., "@ecommerce-mcp-automationrun the daily P&L and ad performance report"
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.
Ecommerce MCP Automation
A sample Claude Code + MCP integration: Shopify and Meta Ads exposed as MCP tools, plus a reporting agent that pulls both into one formatted daily P&L + ad-performance spreadsheet — no manual copy-paste between platforms.
This is a demonstration built against the public Shopify Admin API and Meta Marketing API docs — not something that has run a real business. It's a clean-room sample: real endpoints, real auth, real pagination, real error handling, written fresh to show exactly how this kind of automation gets built. It runs end-to-end in mock mode with zero credentials (realistic fixture data standing in for live responses), and switches to live mode per-integration the moment real credentials are set — see How to run.
The Shopify client has been run live against a real Shopify Partners development store (a sandbox store, not a production business) — real auth, a real order, real API responses. That process surfaced and fixed two real nullability edge cases (see Known simplifications) that the mock fixtures alone hadn't covered. Meta Ads runs against the mock transport by default in this repo; the client code is written the same way and switches to live the moment
META_ACCESS_TOKEN/META_AD_ACCOUNT_IDare set.
What it does
Exposes Shopify orders, revenue, and COGS as MCP tools (
get_orders,get_daily_pnl)Exposes Meta Ads spend, impressions, purchases, and ROAS as MCP tools (
get_insights,get_daily_ad_performance)Runs a reporting agent (
daily_report.py) that pulls both concurrently and writes a formatted.xlsx— Summary, Orders, and Ad Performance sheetsShips a Claude Code Skill that wraps the whole workflow behind a natural-language trigger ("run the daily report")
Includes a committed sample output so the result is visible without running anything
Related MCP server: Presso MCP Server
Sample output
Rendered preview of the Summary tab — open the actual generated workbook for the live file (with the Orders and Ad Performance sheets, currency/ROAS formatting, and frozen header rows).
Architecture
flowchart LR
subgraph Shopify["Shopify Admin API"]
SO[orders.json]
SI[inventory_items.json]
end
subgraph Meta["Meta Marketing API"]
MI[act_id/insights]
end
SO --> SC[shopify_client.py]
SI --> SC
MI --> MC[meta_ads_client.py]
SC --> SS[shopify_server.py<br/>MCP tools]
MC --> MS[meta_ads_server.py<br/>MCP tools]
SC --> DR[daily_report.py]
MC --> DR
DR --> SPX[spreadsheet.py]
SPX --> XLSX[(sample_daily_report.xlsx)]
Mock[["mock_api.py<br/>(ASGITransport, in-process)"]] -.mock mode.-> SC
Mock -.mock mode.-> MCThe two API clients (clients/shopify_client.py, clients/meta_ads_client.py)
are genuine integration code — real endpoint URLs, real auth headers, real
pagination loops, real 429 backoff. The only thing that changes between
mock and live mode is the HTTP transport (clients/http.py):
Live:
httpx.AsyncClientopens a real connection to Shopify / Meta.Mock:
httpx.AsyncClientis given anhttpx.ASGITransportpointed at an in-process FastAPI app (fixtures/mock_api.py) serving realistic fixture payloads. No port is bound, no subprocess runs — but requests still travel through genuine HTTP/ASGI routing, headers, and JSON encoding.
That means the client code a reviewer reads is the same code that would run against a live store — not a mock dressed up to look like one. See CLAUDE.md for the full conventions.
How to run
Mock mode (default — zero credentials)
git clone <this-repo> && cd ecommerce-mcp-automation
python -m venv .venv && source .venv/bin/activate # or: uv sync && source .venv/bin/activate
pip install -e ".[dev]"
python -m ecommerce_mcp.reporting.daily_report
# -> Wrote examples/sample_daily_report.xlsxRun the test suite the same way, no setup needed:
pytestLive mode
Copy .env.example to .env and fill in what you have — each integration
switches to live independently the moment its own credentials are present,
so you can run Shopify live with Meta still mocked (or vice versa):
cp .env.example .env
# SHOPIFY_STORE_DOMAIN=your-dev-store.myshopify.com
# SHOPIFY_ACCESS_TOKEN=shpat_... (Partners dev store -> custom app -> Admin API token)
# META_ACCESS_TOKEN=EAA... (System User token, ads_read scope)
# META_AD_ACCOUNT_ID=act_1234567890As MCP servers (Claude Code / Claude Desktop)
Add to your MCP config (.mcp.json for Claude Code, or Claude Desktop's
config file). Point command at the project's venv interpreter directly —
MCP clients don't source your shell profile, so a bare python won't see an
activated venv:
{
"mcpServers": {
"shopify": {
"command": "/path/to/ecommerce-mcp-automation/.venv/bin/python",
"args": ["-m", "ecommerce_mcp.mcp_servers.shopify_server"],
"cwd": "/path/to/ecommerce-mcp-automation"
},
"meta-ads": {
"command": "/path/to/ecommerce-mcp-automation/.venv/bin/python",
"args": ["-m", "ecommerce_mcp.mcp_servers.meta_ads_server"],
"cwd": "/path/to/ecommerce-mcp-automation"
}
}
}Then ask Claude things like "what's today's Shopify P&L?" or "get me yesterday's Meta ad performance" — it'll call the tools directly, in mock mode by default.
As a Skill
skills/daily-report/SKILL.md wraps the report-generation workflow so
Claude Code runs it on a natural-language trigger ("run the daily report")
rather than needing the exact CLI command. The full-report path doesn't
need the MCP config above at all — it runs daily_report.py directly,
which calls the clients as plain Python, no MCP involved. MCP config is only
needed for the Skill's other path: answering a one-off single-metric
question ("what's today's ROAS?") by calling get_daily_pnl /
get_daily_ad_performance as MCP tools instead of running the whole report.
Project layout
src/ecommerce_mcp/
clients/ Typed, async API clients (Shopify + Meta), transport-swappable
mcp_servers/ MCP tool servers wrapping the clients
reporting/ daily_report.py (orchestration) + spreadsheet.py (openpyxl)
fixtures/ Realistic mock payloads + the in-process mock API app
skills/daily-report/ Claude Code Skill for the reporting workflow
tests/ pytest suite (all run against mock mode)
examples/ Committed sample .xlsx + README preview imageKnown simplifications
Documented here rather than hidden, since precision matters more than polish for a sample like this:
COGS uses Shopify's
InventoryItem.costfield via the real two-hop lookup (variant →inventory_item_id→ batchedinventory_itemsfetch) — Shopify doesn't expose cost on the order line item directly. Bothcostand line-itemskuare nullable on a live store (a merchant may never have set them) — found via live testing against a real dev store, not from the docs alone. Both are handled as zero-cost / missing-SKU rather than erroring.Refunded orders are excluded entirely from revenue/COGS/order count in
daily_pnl(). Partial refunds/returns accounting would need the Refund resource — out of scope here.Meta purchase attribution uses the
purchaseaction type from theactions/action_valuesarrays at whatever attribution window the ad account is configured with — this client doesn't override it.The reporting agent currently pulls all available orders/insights rather than filtering by date range; a production daily cron would pass
created_at_min/time_rangefor the target day.
License
MIT — see LICENSE.
Available Tools
2 toolsget_daily_pnlA
Revenue, COGS, and gross profit across the current order set.
COGS is resolved per line item via the Shopify inventory item cost field. Refunded orders are excluded.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It usefully explains that COGS is resolved per line item and that refunded orders are excluded. However, it does not define what 'current order set' means or how the 'daily' period is determined, leaving ambiguity in the tool's scope.
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 compact and front-loaded, with the core metrics stated in the first sentence. Every subsequent line adds distinct value: cost-resolution method and refund exclusion. There is no redundancy or filler.
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?
There is no output schema or annotations, so the description must communicate both the result metric and behavioral caveats, which it does adequately for a zero-parameter tool. The main gap is that the exact time period of 'current order set' is left undefined.
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 tool has zero parameters and the schema covers everything about parameters, so the description does not need to explain parameter semantics. It still adds meaning by describing what the computed values represent, which is sufficient given no parameters exist.
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 opens with the specific metrics 'Revenue, COGS, and gross profit' and names the resource 'current order set.' This clearly distinguishes the tool from its sibling get_orders, which would return orders rather than a financial summary.
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 gives helpful context such as 'across the current order set' and 'Refunded orders are excluded,' but it does not explicitly state when to use this tool versus get_orders or when not to use it. Usage guidance is implied rather than clearly articulated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ordersA
Fetch Shopify orders (paginated automatically).
Args: status: Order status filter — "any", "open", "closed", or "cancelled".
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | any |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It usefully discloses that pagination is handled automatically, which is a non-obvious behavior an agent needs to know. It does not mention auth or rate limits, but for a simple fetch operation the pagination disclosure is meaningful.
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?
Two concise sentences cover purpose, pagination behavior, and the parameter's allowed values. Every sentence earns its place, and the most important information is front-loaded.
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 one-parameter fetch tool with an output schema, this description is complete. It covers what the tool does, the parameter semantics, and a key behavioral detail (automatic pagination). The sibling tool is clearly distinct, so no additional routing context is necessary.
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%, so the description must compensate. It fully defines the only parameter, status, and lists all allowed values: 'any', 'open', 'closed', or 'cancelled'. This adds clear meaning beyond the schema, which only shows type and default.
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 states a specific action and resource: 'Fetch Shopify orders'. The automatic pagination note adds scope, and the sibling get_daily_pnl is clearly a different resource, so an agent can distinguish them without opening schemas.
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 order data is needed and offers a status filter, but it does not explicitly say when to use this tool versus get_daily_pnl or any other alternative. There are no exclusions or conditional routing cues.
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.
2 tool updates
v0.1.0- First observed
get_daily_pnl - First observed
get_orders
TDQS
Scored across 2 tools
get_orders returns raw order data, while get_daily_pnl computes financial metrics. Their purposes are entirely distinct with no overlap, making tool selection unambiguous.
Both tools follow the consistent get_<noun> pattern, which is clear and predictable. There is no mixing of styles or ambiguous verbs.
With only two tools, the set feels thin for a server labeled 'ecommerce automation'. However, it is not a single trivial tool, so borderline is appropriate.
The server provides only read-only order access and a PnL report. There are no create/update/delete operations, product or customer tools, refund handling, or broader automation workflows, making the surface severely incomplete for ecommerce automation.
Maintenance
Related MCP Connectors
Connects Amazon Seller Central and Amazon Advertising to any MCP client. Settlement-accurate P&L - every fee, refund and reimbursement as Amazon posted it - plus contribution margin and breakeven per product, per marketplace, per day. Full Sponsored Products, Brands and Display management: search terms, placements, keyword and competitor research, dayparting, automation rules. 107 tools: 72 read-only, 29 that stage a reviewable diff for your approval, and 6 confirmation/support actions. Write tools stage a reviewable diff; applying it takes a separate confirmation.
Meta Ads MCP (Facebook + Instagram) - analyze performance, manage budgets, pause campaigns.
Google Ads, Meta Ads & GA4 MCP server - 250+ tools for campaigns, creatives, audiences & reports.
First-party unsampled Shopify analytics MCP — sessions, attribution, funnels, leaks. 26 tools.
Related MCP Servers
- AlicenseAqualityFmaintenanceFree, open-source MCP server that connects Claude to the Shopify Partner API. 25 tools for revenue analytics, churn analysis, retention cohorts, merchant health scoring, conversion funnels, revenue forecasting, and growth velocity.2513MIT

Presso MCP Serverofficial
AlicenseNot gradedqualityDmaintenanceConnects e-commerce and marketing data sources like Shopify, GA4, Google Ads, and Meta Ads to AI assistants, enabling natural language queries about store performance, ad campaigns, and customer behavior.7 npm2MIT- FlicenseNot gradedqualityCmaintenanceHosted MCP server connecting Shopify, Klaviyo, GA4, Meta Ads, Google Ads, Xero, Gorgias and 20+ e-commerce data sources so AI assistants can answer merchant questions that span every source at once.-
- AlicenseNot gradedqualityCmaintenanceConnects Claude to Meta Ads, enabling full management of ad accounts including campaigns, creatives, budgets, and reporting. Handles authentication, token minting, and MCP server registration automatically.MIT