Case study 05

A marketing department, encoded as twelve Claude Code skills.

Competitor research, content, SEO, ads, cold outreach, and community-specific posting for eleven platforms, all built around one rule that isn't a suggestion: nothing goes out until a human reads the real thing and says so, live.

Role
Sole designer & builder
Timeframe
4 days · Sep 2026
30 commits, shipped iteratively
Built with
Claude Code Agent Skills
Python, Markdown-based state
Status
Installable plugin
public repo, MIT-licensed
12composable skills, one setup command
11+platforms with a scripted send path
~4,800lines of skill specs & docs
~1,100lines of dependency-free Python
0sends that happen without a human reply
The problem

A solo founder needs five job functions and can't hire for any of them.

Competitor intelligence, content production, SEO, paid ad copy, cold outreach, community management, and publishing operations are normally five different people's jobs. A small team either drops most of them or does each one shallowly, in whatever time is left over.

Most "AI marketing" tools solve the drafting half of that problem well. Fewer stop to ask whether the posting half should be automatic too, even though that half carries the real consequences: your brand voice, your sender reputation, your standing in the communities that ban self-promotion the moment they smell it. The interesting design problem here wasn't "write good marketing copy." It was building a system a non-technical operator could actually trust not to embarrass them while they weren't watching.

What I built

Twelve skills, five jobs, one shared config.

Each skill is a self-contained agent specification: trigger phrases, a step-by-step process, and an exact output structure. Every one of them reads the same brand-voice file, so tone, audience, and banned words are set once and honored everywhere.

Research

competitor-research
Full competitor brief: overview, recent moves, messaging analysis, a real SWOT, sourced recommendations.

Produce

content-calendar
Batch-generates dated, platform-tagged posts, checked against history so it never repeats a recent topic.
content-repurposer
One source in; a LinkedIn post, an X thread, and a newsletter blurb out, in one pass.
seo-brief
Keywords, search intent, outline, meta title/description. Never invents a search-volume number.
ad-copy-generator
Multiple variants per platform, each a distinct hook angle, sized to that platform's limits.
email-sequence
A multi-email drip with send timing, subject lines, and an actual narrative arc across emails.
visual-brief-generator
Shot list, per-scene prompts, aspect ratios, style guide. Generates the asset only if a tool is connected.
short-form-video
Hook-first script and a ready-to-post package for Shorts, Reels, and TikTok: caption, hashtags, best-time-to-post.

Reach out

email-outreach
Researches real prospects, personalizes each email, dedupes against a permanent contact log, refreshes strategy monthly.

Belong

community-post-generator
Researches a specific community's actual rules before drafting anything, and gives a plain No-Go when they say no.

Ship

publish-pipeline
Packages content to JSON, shows the exact payload, and hands off to your automation or a platform API.
full-pipeline
Chains research, content, and visuals into one run, still stopping at the same approval gate before anything sends.

+ /marketing-skill:marketing-setup — the one command every skill above reads its defaults from

Engineering decisions

The parts that were actually hard.

Getting a model to write a decent LinkedIn post is a solved problem. These are the six decisions that turned twelve drafting skills into a system worth trusting with a real account.

Governance

Generation and approval are different jobs, and the file format enforces it.

Any skill that drafts content can only ever write Planned, Drafted, or Ready for Approval to a row's status in the shared state file. Only publish-pipeline is allowed to write Approved, and only in the same turn where it has shown the real content to a person and gotten an actual reply back.

A blanket instruction like "just post these," silence, a timeout, or a scheduled trigger firing with nobody around to answer all fail that check the same way. The diagram below is the whole mechanism.

A skill drafts content one of nine content / outreach skills writes + queues Ready for Approval state/content-calendar.md row shown live, verbatim Explicit reply in this chat? no reply / timeout Nothing sent stays queued for next time yes, explicit reply Approved human said go, live, this turn publish-pipeline sends Sent webhook or direct platform API
The only path from drafted to sent runs through a live human reply. Dashed lines mark the alternative: a scheduled run with nobody there to answer leaves the row exactly where it was — Ready for Approval, not gone, not sent.
Data integrity

A suppression list that keeps itself honest.

Cold outreach lives or dies on never re-contacting someone who already said no. Every run opens by syncing the connected Gmail inbox: a real reply becomes Replied, a bounce notice becomes Bounced, opt-out language becomes Unsubscribed, and all three permanently block that contact from ever being re-queued, no matter how a later request is phrased.

Anything genuinely ambiguous gets reported, not guessed at. The log itself is append-only, so it doubles as an audit trail of exactly who was contacted, when, and why they stopped being.

Research discipline

Eight communities, eight rulebooks, one honest No-Go.

community-post-generator doesn't reuse one template across Reddit, Product Hunt, Hacker News, Indie Hackers, dev.to, Discord, Slack, and Telegram. It researches that specific target's actual rules first, or, where no public rules page exists, asks the person who's actually a member, and will flatly say a post isn't welcome rather than draft something polished that gets removed anyway.

Building it surfaced a real failure mode. One early research pass on "Indie Hackers" was actually describing r/indiehackers, a same-named subreddit that isn't the site at all. The fix was a source-verification step that confirms a source is genuinely about the named target before anything gets drafted from it.

Extensibility

Skills check what's connected. They don't assume it.

visual-brief-generator, short-form-video, and email-outreach each check the current session for a relevant connected tool, an image or video generator, Gmail, a prospecting service, at runtime instead of hardcoding one. Nothing connected still produces a complete, usable brief or draft. Something connected upgrades the same skill's output with no code change.

Being connected never implies being willing to spend, either: credit-metered tools still show projected cost and wait for a go-ahead before using it.

Defensive scripting

No script here has a default that sends.

Both hand-off scripts, the webhook sender and the direct-to-platform poster, refuse to run at all unless called with exactly --dry-run or --confirmed. Dry-run prints the literal request, with credentials redacted to match what each platform actually treats as secret: the full URL for a Discord or Slack webhook, just the token segment inside a Telegram URL, a single header value for a dev.to API key.

Nothing sends by accident, because nothing sends by default.

Shared configuration

Define voice once. Let strategy remember its own age.

Every skill reads the same brand-voice.md for tone, audience, and banned words, set once through a four-question setup instead of re-asked per skill. email-outreach's own strategy file goes one step further: the skill checks its own last-refreshed date on every run and walks through a strategy-refresh conversation once 30 days have passed, using the accumulated send, reply, and bounce counts to inform it.

No external scheduler, cron job, or reminder is needed. The cadence lives inside the skill itself.

Platform research

Eleven platforms, and no two of them work the same way.

Part of this build was simply reverse-engineering how eleven different platforms actually let you post, since none of them share a credential model, a formatting syntax, or an approval process.

PlatformHow the draft gets researchedHow it actually ships
LinkedIn, X, MetaFixed brand-voice templateDirect API, your own app credentials
RedditLive per-subreddit rules + style sampleDirect API (manual approval queue since late 2025)
Product HuntLive guideline researchDraft only — write API needs Product Hunt's own approval
Hacker NewsLive guidelines + Show HN normsDraft only — the API is read-only by design
Indie HackersLive research, source-verifiedDraft only — no confirmed write API exists
dev.toSitewide + per-tag rulesDirect API — the simplest credential of the eight
DiscordAsks the member — no public rules pageWebhook — easiest access, hardest research
SlackAsks the member; drafted in mrkdwnApp/webhook — often needs admin approval first
TelegramLive preview if public, otherwise asksBot via BotFather — a chat admin still has to add it
Shorts, Reels, TikTokshort-form-video's script, caption, hashtags, timingThree different models: self-serve upload, a 3-step Graph API flow, or an audited API
Outcome

What one operator can actually run with this.

Put together, the twelve skills behave less like a content generator and more like a small marketing team with one person directing it: competitor research on Monday morning, a week of platform-tagged posts queued by lunch, a freshly researched and individually personalized outreach batch going out that afternoon, and a Reddit post that's already been checked against that subreddit's actual rules before it was ever drafted.

None of it reaches an inbox, a feed, or a webhook until a person reads the real thing and says go.

That last part is the actual product. Anyone can wire an LLM to an API and call it "automation." The harder, more useful thing is building automation with a governor built in, one that a founder can hand their real accounts to without spending the next month checking it hasn't posted something unhinged to a subreddit at 2am.

Skills demonstrated
Agent & skill system design Safety-first / governance architecture API research across 11+ platforms Python — dependency-free tooling State-machine & data-model design Technical specification writing Graceful degradation by design
claude plugin marketplace add marcosmodly/marketing-skill
claude plugin install marketing-skill@marketing-skill
# or copy skills/* straight into ~/.claude/skills/

Case study written from the project's own commit history, source, and documentation.