Jason Hartley AI Agent Systems Engineer

// MCP Server

PK Command, a custom MCP server connecting Claude to Meta Ads, Mailchimp, Shopify, and Postgres

Model Context Protocol server that lets Claude operate four production APIs safely with confirm-gate write protection. Replaces ~10 hours per week of manual ops work.

MCPClaude APITypeScriptPostgresMeta Ads APIMailchimp APIShopify Admin API
// pk-command mcp · awaiting confirm
$ meta_creative_update
ad_id: "6701892334...",
link_url: "/pages/the-forge-run"
}
// proposal returned
{
"action_id": "act_8f2a14b9c0",
"action": "update_creative",
"target": "Forge Run · v3.2",
"changes": {
"link_url": "/pages/the-forge-run"
},
"status": "awaiting_confirm"
}
> confirm act_8f2a14b9c0?

The problem

Running an ecommerce operation means living in four browser tabs: Meta Ads Manager, Mailchimp, Shopify, and a content calendar. Most of the work in those tabs is repetitive lookups and small mutations: “what is this campaign’s ROAS this week,” “schedule this email for Tuesday,” “tag these orders,” “update the brief on this post.” A general-purpose chat assistant cannot do any of it directly. A custom dashboard takes weeks to build per surface and still leaves the assistant outside the loop.

The architecture

A single MCP server exposing scoped tools across all four APIs, with a uniform confirm-gate pattern on every write. Read tools return live data straight from the API. Write tools return a structured proposal with an action_id. The actual mutation only fires when the human confirms with that id. The same pattern applies whether the target is a $500 ad campaign or a single line edit on a Shopify article.

  • Each API surface is its own module: meta-ads, mailchimp, shopify, content-calendar (Postgres). Modules share a common action-gate utility, not a common API client. This keeps blast radius per surface contained.
  • Tools are designed for the conversational shape of the work, not as a 1-to-1 mirror of REST endpoints. A single meta_creative_update tool replaces what would otherwise be 4 raw API calls plus error handling.
  • Action gate is structural: every destructive tool returns { action_id, summary, target, changes }, the human confirms, and a separate confirm_action tool executes. The agent does not silently retry.
  • Bulk operations are first-class: meta_creative_bulk_update runs the same change across many ads with per-ad error handling and a summary report.
  • The whole server runs as a single PM2 process and is reachable through Claude Code, Claude Desktop, and the Claude API.

What it does in production

  • Removes a class of daily ops work that previously required four browser tabs.
  • Has handled hundreds of structured writes across Meta, Mailchimp, Shopify, and the content calendar with the confirm-gate intact.
  • Surfaces are added in days, not weeks, because the action-gate scaffolding is reused.

What I would do differently

The first version returned write results as freeform JSON. The current version returns a structured { action_id, before, after, summary } shape, which the LLM can then describe back to the user before the confirm step. That structural change made the confirm-gate pattern materially safer and is the pattern I would now design in from day one.

Get in touch

Currently booking new engagements. Send a brief and I'll respond within 24 hours.

Send a brief →