Skip to main content
Jun 25, 2026 · 7 min

MCP-first marketing ops

Why I wrapped every data source — Shopify, Meta Ads, Search Console — as its own MCP server instead of one big script. The boring decision that makes it composable.

Khoa

When you build a marketing OS as one person, the first real architectural decision is also the least glamorous: how do you talk to the data? Meta Ads, Shopify, Google Search Console, GA4 — each has an API, and the obvious move is to call them all from one big Python script. I didn't. I wrapped every source as its own Model Context Protocol (MCP) server, and that one choice quietly shaped everything after it.

The shape

Three layers, each ignorant of the others' internals:

LayerWhat it isExample
AdaptersOne MCP server per data sourceshopify, meta_ads, gsc, ga4
SkillsMarkdown-defined analyses that call adapters"daily revenue summary," "SEO striking-distance"
WorkflowsPython on a schedule that runs skills7am daily report → inbox + Drive

A skill never touches an API directly. It asks the shopify adapter for orders and the meta_ads adapter for spend, and it doesn't know or care how either one authenticates. That separation is the whole game.

Why MCP instead of a monolith

Four reasons, and none of them is hype.

It's IDE-agnostic. The same adapters work whether I'm driving them from Claude Code, Claude Desktop, or another editor. The intelligence isn't welded to one tool's plugin system — it's a protocol any of them speak. I can change how I work without rewriting what I built.

It's composable. Because every source is a uniform server, a single skill can pull from three of them at once — correlate Meta spend against Shopify revenue against Search Console impressions in one analysis — without any bespoke glue. New combinations are free.

It's testable. Adapters and analysis are separable, so I can mock an MCP server's responses and test a skill's logic without burning live API quota or waiting on a real account. The thing that makes the analysis trustworthy is that I can test it in isolation.

It's future-proof for autonomy. When the system eventually graduates from describing to acting, the action surface is already a clean set of tools with clear boundaries — not a tangle of inline API calls I'd have to audit line by line.

The cost, honestly

It isn't free. Every adapter is more boilerplate than a quick API call would be, and there's a real learning curve to building MCP servers well. For a weekend hack, a monolith is faster.

But this isn't a weekend hack — it's a system meant to grow for months and maybe outlive its first use. At that horizon the monolith is the expensive choice: the one where every new data source touches everything, every test needs live credentials, and moving tools means a rewrite. The boilerplate is a premium I'm paying up front to keep the thing composable and replaceable forever.

A skill that proves the shape

The one that made the architecture click for me: a "daily revenue summary" skill in Jarvis, my marketing OS. It asks the shopify adapter for yesterday's orders, the meta_ads adapter for yesterday's spend, and the ga4 adapter for sessions — three separate MCP calls, one analysis. The skill's markdown file is twelve lines. It doesn't know that Shopify uses GraphQL, that Meta needs a paginated cursor, or that GA4's API has a 10,000-row limit. It just asks for numbers and gets them.

When Meta changed their API version in early 2026, I updated one adapter. Twelve lines of skill markdown didn't change. The daily report ran the next morning like nothing happened. In a monolith, that API change would have meant touching every script that calls Meta — and I'd have found out about the breakage at 7am when the report didn't arrive.

What I'd do differently

I built four adapters in the first week. That was two too many. The gsc and ga4 adapters sat unused for a month because I didn't have a skill that needed them yet. I'd built them because I knew I'd need them, and the building felt productive. It wasn't. It was inventory.

Now I follow a rule: build an adapter when a skill demands it, not when a roadmap suggests it. The content fence taught me the same lesson on SoiTarot — build the constraint, then build what's inside it. Don't build the fence around a field you haven't decided to farm. The MCP shape made adding the fifth adapter trivial when the time came. That's the point. You don't need to build it early. You need to build it right, so that late is cheap.

The quiet payoff

The reason this matters beyond my own setup: MCP turns "marketing data" into Lego. Once a source is a server, anyone's skill can use it, including future-me's. It's the same instinct as the content fence and the demo-driven discipline — spend a little structure now so that everything downstream gets cheaper and more trustworthy. Boring, on purpose. Boring is what compounds.