Shopify Content Engine MCP Server
Enables agents to validate product content drafts and trigger the Shopify AI content engine workflow to generate complete marketing kits including SEO, ads, blog posts, and images.
README
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 (clinically, certified, vegan, …) not present in the product input. |
| Fragile parsing | All three model calls use OpenAI Structured Outputs (strict: true) — schema-valid JSON, no regex. |
| Re-runs / cost | An idempotency gate skips anything already status=done; forceRegenerate overrides. Bulk model is gpt-4o-mini. |
| One bad product | Per-call retry + continue-on-error. Failures are written as status=failed rows with a failure_reason (dead-letter) — the batch never stops. |
| Uncaught failures | Routed to a separate Error Handler workflow → alert email. |
| Testing without side effects | dryRun=true generates and validates but writes nothing. |
| Publishing | Never automatic. Drafts land in the Review tab and a human approves. |
| Platform limits | Hard caps (SEO title ≤ 60, meta ≤ 155, Google headline ≤ 30, X ≤ 280, …) live in config/, are enforced in the Parse node, and are re-checked by the evals. |
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 email
Full 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 | status=done, all 19 content fields present |
| 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 {PRODUCT_URL} CTA, slug format |
| SEO placement | primary keyword in title / meta / first sentence (warnings) |
| Brand voice | banned words from brand-voice.yaml |
| Facts-only | numbers+units and claim words in the output must exist in the product input |
LLM judge (--judge) |
1–5 on facts-only, brand voice, SEO quality + quoted unsupported claims (Structured Outputs, opt-in, needs OPENAI_API_KEY) |
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 |
|---|---|
get_brand_voice |
voice, audience, banned words, facts-only rule |
get_generation_limits |
the hard caps + run flags |
list_sample_products |
the five fixture products |
validate_content_kit(row, product) |
score a draft with the same rules as the evals |
run_content_engine(dry_run=True, …) |
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
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.