Shopify Content Engine MCP Server
Shopify Product Content Engine
An n8n pipeline that turns a bare product (product_name, product_description) into a complete,
review-ready marketing kit — SEO research, product-page copy, a blog post, Google + Meta ads,
social posts, an email and a hero image — and writes one row per product to a review sheet.
Nothing publishes automatically; a human approves.
Alongside the workflow this repo ships the two things that make it operable rather than a demo: an eval harness that scores every generated kit against the engine's own rules (length caps, banned words, invented facts) and an MCP server so any agent — Claude Desktop, Claude Code, Cursor, your own — can validate drafts and trigger runs.
product_name + product_description
│
▼
┌────────────── n8n ──────────────┐
│ idempotency gate → 3 LLM calls │──▶ Review sheet (status=done | failed)
│ strict JSON → validate → map │──▶ hero image → Drive
│ dry-run · retry · dead-letter │──▶ batch summary email
└─────────────────────────────────┘
▲ │
MCP server eval harness
(validate / run) (rules + LLM judge, gates CI)Why it's built this way
Concern | What the engine does |
Hallucinated specs | Every prompt is facts-only; the eval flags any number/unit or claim word ( |
Fragile parsing | All three model calls use OpenAI Structured Outputs ( |
Re-runs / cost | An idempotency gate skips anything already |
One bad product | Per-call retry + continue-on-error. Failures are written as |
Uncaught failures | Routed to a separate Error Handler workflow → alert email. |
Testing without side effects |
|
Publishing | Never automatic. Drafts land in the |
Platform limits | Hard caps (SEO title ≤ 60, meta ≤ 155, Google headline ≤ 30, X ≤ 280, …) live in |
Flow
Manual / Schedule / Webhook ─▶ ⚙️ Config ─▶ 📥 Read Products [swap point → Shopify]
─▶ 📖 Read Done ─▶ 🚦 Idempotency Gate ─▶ 🔢 Limit ─▶ 🔁 Loop (1 product at a time)
─▶ 🤖 A: SEO + Product Page ─▶ 🤖 B: Blog ─▶ 🤖 C: Ads / Social / Email / Image prompt
─▶ 🧩 Parse, Validate & Map ─▶ 🧪 Dry run?
├─ yes ─▶ 📝 Dry-run log (no write) ─▶ loop
└─ no ─▶ 🖼️ Images? ─▶ 🎨 gpt-image-1 ─▶ ☁️ Drive ─▶ 📤 Upsert Review row ─▶ loop
🔁 done ─▶ 📊 Batch summary ─▶ ✉️ Email (optional)
(uncaught) ─▶ ⚠️ Error Handler workflow ─▶ alert emailFull Mermaid diagram: docs/architecture.mmd.
Product source is a Google Sheet today; 📥 Read Products is a marked swap point for
Shopify → Get Products (title → product_name, body_html → product_description).
Evals
python -m evals scores kits (Review-tab rows) against the rules the engine promises to keep.
Rules come straight from config/generation.config.yaml and config/brand-voice.yaml, so
changing a cap in config changes the eval.
Check family | Examples |
Completeness |
|
Hard caps | 8 character caps, 3 word ranges, ≤15 Google headlines each ≤30 chars, 5–10 hashtags |
Structure | 4–6 bullets, H2/H3 in the blog, exactly one |
SEO placement | primary keyword in title / meta / first sentence (warnings) |
Brand voice | banned words from |
Facts-only | numbers+units and claim words in the output must exist in the product input |
LLM judge ( | 1–5 on facts-only, brand voice, SEO quality + quoted unsupported claims (Structured Outputs, opt-in, needs |
Current golden set (real kit from a live run, evals/golden/kits.json):
Product | Score | What it caught |
Gentle Hydrating Gel Cleanser | 88% | description 66 words (want 150–250), blog 507 words (want 900–1200), email 28 words (want 60–120) — the model under-delivers on length; the Parse node truncates over-length text but has no minimum-length retry yet |
That finding is exactly why the harness exists — it's now an open item (see roadmap). Run it
against your own export with python -m evals --input review-export.csv --min-score 0.9; the
non-zero exit code gates CI.
MCP server
mcp_server/ exposes the engine over the Model Context Protocol (stdio):
Tool | Purpose |
| voice, audience, banned words, facts-only rule |
| the hard caps + run flags |
| the five fixture products |
| score a draft with the same rules as the evals |
| POST the workflow webhook with per-run flags — dry-run by default |
Resources: content-engine://columns (Review sheet column map), content-engine://prompts/{A|B|C}.
Claude Desktop / Claude Code config:
{
"mcpServers": {
"shopify-content-engine": {
"command": "content-engine-mcp",
"env": { "N8N_WEBHOOK_URL": "https://<your-instance>/webhook/shopify-content-engine-run" }
}
}
}Repo layout
workflows/ shopify-content-engine.workflow.json · error-handler.workflow.json (import these)
prompts/ system prompts A / B / C + prompt library (version-controlled mirror of ⚙️ Config)
config/ brand-voice.yaml · generation.config.yaml (limits, flags)
docs/ runbook.md · architecture.mmd · output-sheet-columns.md
test/ product-fixtures.json (5 products) · dry-run checklist · a real generated kit
evals/ checks.py (rules) · judge.py (LLM judge) · golden/ · tests/
mcp_server/ server.py · tests/
scripts/ check_workflows.py — static checks on the exported JSON (runs in CI)Quick start
Workflow
Import
workflows/error-handler.workflow.json, thenworkflows/shopify-content-engine.workflow.json.Re-select credentials on the OpenAI / Google Sheets / Drive / Gmail nodes (never stored in the JSON).
Point
📥 Read Products,📖 Read Done,📤 Writeat a sheet with tabsProductsandReview.Set Settings → Error Workflow to the imported error handler.
Dry-run the five fixtures (
test/README.md), then run for real. Run flags can be posted in the webhook body:{"dryRun": true, "enableImages": false}.
Evals + MCP
pip install -e ".[mcp,dev]"
python -m evals # score the golden set
python -m evals --input export.csv # score your own Review-tab export
pytest # 27 tests: rules, negative cases, MCP tools in-process
content-engine-mcp # start the MCP server (stdio)Roadmap
Minimum-length guard + one self-correcting retry in the Parse step (the eval currently flags short copy after the fact).
Header-auth on the webhook trigger (n8n credential) — today it relies on the unguessable path.
Shopify Admin API as the product source and a
Draft productwrite-back behind the same approval gate.Golden set: more real kits, one per fixture, and a nightly
--judgerun.
License
MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/AbdulRehman0004/shopify-ai-content-engine'
If you have feedback or need assistance with the MCP directory API, please join our Discord server