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.
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.
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
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.
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 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.
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.
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.
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.
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.
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.
| Platform | How the draft gets researched | How it actually ships |
|---|---|---|
| LinkedIn, X, Meta | Fixed brand-voice template | Direct API, your own app credentials |
| Live per-subreddit rules + style sample | Direct API (manual approval queue since late 2025) | |
| Product Hunt | Live guideline research | Draft only — write API needs Product Hunt's own approval |
| Hacker News | Live guidelines + Show HN norms | Draft only — the API is read-only by design |
| Indie Hackers | Live research, source-verified | Draft only — no confirmed write API exists |
| dev.to | Sitewide + per-tag rules | Direct API — the simplest credential of the eight |
| Discord | Asks the member — no public rules page | Webhook — easiest access, hardest research |
| Slack | Asks the member; drafted in mrkdwn | App/webhook — often needs admin approval first |
| Telegram | Live preview if public, otherwise asks | Bot via BotFather — a chat admin still has to add it |
| Shorts, Reels, TikTok | short-form-video's script, caption, hashtags, timing | Three different models: self-serve upload, a 3-step Graph API flow, or an audited API |
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.
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.