| name | content-factory-installer |
| description | Set up a personalized LinkedIn Content Factory — an AI agent team that mines your meeting transcripts for post ideas, writes in your voice, and produces a week of LinkedIn content. Guided installer: checks prerequisites, interviews you to build your voice profile, creates a self-contained content factory skill. Triggers on: "install content factory", "set up content factory", "content factory setup", "/content-factory-installer".
|
Content Factory Installer
A guided wizard that sets up a personalized LinkedIn Content Factory for any
user. The factory is an agent team that mines meeting transcripts, writes posts
in your authentic voice, and produces a full week of LinkedIn content.
What you'll get: One self-contained skill that runs an agent team (Miner,
Researcher, Writer, Synthesizer, Reviewer) to produce LinkedIn posts from your
real conversations and experiences. No copy-paste templates — posts built from
your actual stories, in your actual voice.
Phase 1: Prerequisites
Step 1.1 — Check for Skill Creator
Check if the Anthropic skill-creator is installed:
ls ~/.claude/skills/skill-creator/SKILL.md 2>/dev/null || ls .claude/skills/skill-creator/SKILL.md 2>/dev/null
If not found, tell the user:
The Content Factory uses Claude Code's skill-creator to build your
personalized skills. Let me install it for you.
Fetch the skill-creator from GitHub:
WebFetch: https://raw.githubusercontent.com/anthropics/skills/main/skills/skill-creator/SKILL.md
Write it to .claude/skills/skill-creator/SKILL.md in the user's project.
Also fetch any supporting files referenced in the skill-creator (agents/,
scripts/, references/, eval-viewer/) from the same GitHub repo base path.
If found, confirm and move on:
Skill creator found. Moving on.
Step 1.2 — Check for Granola
Ask the user:
Do you use Granola (https://granola.ai) to record your meetings?
If yes:
Check if Granola MCP is configured:
cat ~/.claude/settings.json 2>/dev/null | grep -i granola
If not configured, guide them:
Granola has an MCP server that lets me read your meeting transcripts
directly. Here's how to set it up:
- Open Claude Code settings:
claude config
- Add the Granola MCP server to your settings
- You'll need your Granola API key — find it in Granola → Settings → API
Alternatively, if you have the Granola desktop app, I can use its local
MCP server. Which do you prefer — API or local app?
Help them configure whichever option they choose. Verify the connection works
by listing recent meetings.
If no:
No problem. The Content Factory works best with meeting transcripts because
your real conversations are the richest source of authentic content. But we
can also work with:
- Notes or documents you write
- Slack conversations (if you have Slack MCP configured)
- Ideas you tell me directly
I'd strongly recommend trying Granola (https://granola.ai) — it records your
meetings and gives you searchable transcripts. The Content Factory really
shines when it can mine your actual conversations for stories.
For now, we'll set up the factory to work with whatever sources you have,
and you can add Granola later.
Record the available sources for Phase 3.
Step 1.3 — Set Up GPTZero (Authenticity Gate)
Every post goes through a GPTZero authenticity check before it's considered
final. This catches AI-sounding text that slipped through the voice filters.
Ask:
The Content Factory uses GPTZero to verify posts sound human before they're
finalized. You'll need a GPTZero API key.
- Go to https://gptzero.me and create an account
- Go to your dashboard → API → grab your API key
- I'll save it to your
.env file
Check if a .env file exists with a GPTZERO key:
grep GPTZERO .env 2>/dev/null
If found, confirm and move on.
If not found, ask the user to paste their API key. When they provide it:
echo "GPTZERO=their_key_here" >> .env
Also create the GPTZero check script in the project:
mkdir -p scripts
Write scripts/gptzero_check.sh with the following content:
#!/bin/bash
set -euo pipefail
export $(grep GPTZERO .env | xargs)
TEXT=$(cat)
PAYLOAD=$(python3 -c "
import json, sys
text = sys.stdin.read()
print(json.dumps({'document': text}))
" <<< "$TEXT")
RESPONSE=$(curl -s -X POST "https://api.gptzero.me/v2/predict/text" \
-H "x-api-key: ${GPTZERO}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "$PAYLOAD")
python3 -c "
import json, sys
data = json.load(sys.stdin)
doc = data.get('documents', [{}])[0]
summary = {
'classification': doc.get('document_classification', 'UNKNOWN'),
'class_probabilities': doc.get('class_probabilities', {}),
'confidence': doc.get('confidence_category', 'unknown'),
'avg_generated_prob': doc.get('average_generated_prob', -1),
'completely_generated_prob': doc.get('completely_generated_prob', -1),
'overall_burstiness': doc.get('overall_burstiness', -1),
'flagged_sentences': []
}
for s in doc.get('sentences', []):
prob = s.get('generated_prob', 0)
if prob >= 0.65:
summary['flagged_sentences'].append({
'sentence': s.get('sentence', ''),
'generated_prob': round(prob, 3),
'perplexity': round(s.get('perplexity', -1), 2),
'highlight_type': s.get('special_highlight_type', '')
})
summary['flagged_sentences'].sort(key=lambda x: x['generated_prob'], reverse=True)
print(json.dumps(summary, indent=2))
" <<< "\$RESPONSE"
Make it executable:
chmod +x scripts/gptzero_check.sh
Verify the key works by running a quick test:
echo "This is a test sentence written by a human." | bash scripts/gptzero_check.sh
If the response comes back with a valid classification, confirm and move on.
If it errors, help the user troubleshoot their API key.
Step 1.4 — Check for Notion (optional)
Ask:
Do you have a Notion workspace where you'd like to publish drafted posts?
This is optional — we can workshop posts right here in the terminal instead.
If yes:
Great. I'll need:
- A Notion MCP server configured (check your Claude Code settings)
- A database to write posts to — I can create one for you, or you can
point me to an existing one
What's the database ID, or should I create a new "LinkedIn Posts" database?
If they want a new database, create one with properties:
- Title (title)
- Author (select)
- Status (select: Drafted, Approved, Posted, Backlog)
- Bucket (multi-select)
- Post Text (rich_text)
- Date (date)
Record the database ID for Phase 3.
If no:
No problem. Posts will be workshopped interactively right here. You can copy
them to wherever you publish from.
Record: output_mode = "terminal"
Step 1.5 — Scan for Existing Context
Before starting the voice interview from scratch, check if the user already
has context files that can give you a head start. Scan for:
ls USER.md user.md profile.md PROFILE.md 2>/dev/null
ls CLAUDE.md .claude/CLAUDE.md 2>/dev/null
ls README.md 2>/dev/null
What to look for in each file:
- USER.md / profile.md: Name, role, company, communication style,
background, interests, working patterns. This is gold — it may already
contain most of what the voice interview would extract.
- CLAUDE.md: Project instructions often reveal the user's domain,
tools, workflows, and priorities. May contain writing rules, brand
voice guidelines, or tone preferences.
- README.md: Company description, product context, target audience.
If rich context is found, pre-populate the voice profile and skip
redundant interview questions:
I found your profile/context files and already know quite a bit about
you. Let me show you what I've gathered, and we can fill in the gaps
rather than starting from scratch.
Present what you extracted and ask only for what's missing (typically:
LinkedIn-specific voice patterns, content goals, anti-patterns, and
posting cadence).
Also check for existing LinkedIn posts or writing samples:
ls *.md content/ posts/ writing/ linkedin/ 2>/dev/null
If found, read them for voice fingerprints before the interview.
If no context files exist, proceed to the full voice interview as
designed.
Phase 2: Voice Discovery
This is the most important phase. We interview the user to build their
authentic voice profile — the DNA that makes every post sound like them,
not like an AI.
Step 2.1 — The Voice Interview
Read references/voice-interview.md for the full interview protocol.
Run through the interview questions. This is NOT a form — it's a conversation.
Ask one question at a time, follow up on interesting threads, pull at details.
The goal is to capture:
- Who they are — role, company, what they do, their professional identity
- Their audience — who reads their posts, what those people care about
- Their topics — what they know about that others don't, their expertise
- Their voice — how they naturally talk, quirks, patterns, humor style
- Their content goals — why they post, what they want to achieve
- Their anti-patterns — what they hate seeing on LinkedIn
- Sample content — existing posts, writing samples, how they text/message
- Posting cadence — how many posts per week, which days
Take detailed notes. Capture exact phrases they use — these are voice
fingerprints.
Step 2.2 — Analyze Existing Content (if available)
If the user has existing LinkedIn posts:
Can you share links to 5-10 of your LinkedIn posts? I'll analyze your
voice patterns, what performs well, and what makes your writing yours.
If they share posts, use WebFetch to pull each one and analyze:
- Hook patterns (what works, what doesn't)
- Structural patterns (length, paragraph style, narrative vs. declarative)
- Voice fingerprints (phrases, cadence, humor, tone)
- Performance patterns (if engagement data is visible)
- Topic categories
If they don't have existing posts:
No worries. I'll build your voice profile from the interview. After your
first few posts, we'll calibrate further based on what you edit.
Step 2.3 — Build the Voice Profile
From the interview and any content analysis, compile:
- Voice fingerprints — specific phrases, cadence patterns, humor style,
sentence structure preferences, how they start/end posts
- Topic territories — 4-6 content buckets customized to their expertise
- Audience profile — who they're writing for, what resonates
- Anti-patterns — what to avoid (both universal LLM tells AND their
personal pet peeves)
- Hook patterns — what opening styles match their voice
- Posting schedule — which days, how many posts per week
Present the voice profile to the user for review:
Here's what I've captured about your voice. Does this feel right? Anything
I'm missing or got wrong?
Iterate until they confirm.
Step 2.4 — Embargoed Topics
Ask:
Are there topics you should NEVER post about? Things like:
- Unannounced product features or roadmap items
- Internal processes that are competitive advantages
- Specific clients who haven't given permission to be named
- Sensitive business metrics
- Anything that could hurt a deal in progress
Create an embargoed topics table from their answers:
## Embargoed Topics
| Topic | Reason | Status |
|-------|--------|--------|
| [topic] | [why it's off-limits] | Hold |
This table gets baked into the content factory skill. The Miner checks
every idea against it before presenting. The Editor checks again in Phase 2.
Ideas matching embargoed topics are silently dropped — never shown to agents
or the user unless they explicitly ask.
If the user says "nothing is off-limits," create the table empty with a note
that they can add topics later. The table structure must exist either way.
Step 2.5 — Define Content Buckets
Based on their topics and posting cadence, create content bucket definitions.
Read references/content-buckets-template.md for the template structure.
For each bucket, define:
- Bucket name
- What it contains (description)
- Source signals (where to find these stories)
- Example hooks that match their voice
- Frequency (which day(s) of the week)
Map buckets to their weekly schedule. If they post 3x/week, they need 3 buckets.
If 5x/week, 5 buckets. Maximum 8 (one per weekday for two authors).
Phase 3: Build the Content Factory
Now use the skill-creator to build a single, self-contained content factory
skill. This is the core deliverable.
Step 3.1 — Prepare the Skill Blueprint
Assemble all the components into a single skill specification. Read
references/factory-blueprint.md for the full template.
The skill must include ALL of the following inline (not as pointers to other
skills):
- Brand voice rules — from the voice profile (Phase 2)
- Anti-patterns — read
references/anti-patterns.md for universal LLM
anti-patterns, plus any personal anti-patterns from the interview
- Post templates — read
references/post-templates.md for structural
templates, customized with their hook patterns
- Content mining logic — how to extract ideas from their sources (Granola
transcripts, notes, Slack, etc.)
- Agent team prompts — read
references/agent-prompts.md for generalized
prompts for Miner, Researcher, Writer, Synthesizer, Reviewer
- Weekly schedule — their posting cadence mapped to content buckets
- Output logic — Notion DB writes OR terminal workshop mode
- Feedback harvesting — how to learn from their edits over time
- Workshop lessons — read
references/workshop-lessons.md for universal
post-writing lessons that apply regardless of voice
Step 3.2 — Create the Skill via Skill Creator
Invoke the skill-creator with intent:
Create a skill called "content-factory" that produces a full week of LinkedIn
content using an agent team. The skill should be completely self-contained —
all voice rules, anti-patterns, templates, agent prompts, and orchestration
logic must be inline, not pointing to external skills.
Provide the assembled blueprint as the skill body. The skill-creator will:
- Write the SKILL.md
- Create reference files as needed
- Test with sample prompts
- Iterate until the skill is solid
Critical: Make sure the skill-creator includes ALL reference content
inline or in the skill's own references/ directory. The user should not
need any other skills installed for the content factory to work.
Step 3.3 — Create Supporting Scripts
If the user has Granola, create any helper scripts needed for transcript
retrieval in the skill's scripts/ directory.
If the user has Notion, create any helper scripts for database writes.
Phase 4: First Run — Interactive Workshop
The first run is ALWAYS interactive. Do not offer autonomous mode yet.
Step 4.1 — Mine Ideas
Run the Miner phase:
- If Granola is available, pull transcripts from the last 7-14 days
- Extract potential post ideas using the mining logic
- Score and rank them against the user's content buckets
Present ideas to the user one by one:
Here are the top ideas I found in your recent conversations. For each one,
tell me: yes (draft it), no (skip it), or save (backlog for later).
Step 4.2 — Workshop Accepted Ideas
For each accepted idea, workshop it interactively:
- Present 3-5 hook options
- Let the user pick or riff on hooks
- Draft the post
- Present for feedback
- Iterate until they're happy
- Run anti-pattern checks
This is the calibration phase. Pay attention to:
- What they change in your drafts (these become workshop lessons)
- What they reject (these calibrate your taste model)
- How they rephrase things (these are voice fingerprints)
Step 4.3 — Save Calibration Data
After the workshop, update the skill's reference files with:
- Workshop examples (before/after pairs from their edits)
- Workshop lessons (patterns from what they changed)
- Updated feedback annotations (what they liked/disliked)
- Refined voice fingerprints (new phrases, patterns discovered)
Phase 5: Autonomous Mode (Post-First-Run)
After the first successful run, present the option:
Your Content Factory is calibrated. On the next run, you can either:
- Interactive mode — I mine ideas and workshop each post with you
(like we just did)
- Autonomous mode — I run the full agent team overnight and produce
a week of drafted posts for you to review
In autonomous mode, 5 agents work in sequence:
- Miner finds ideas in your transcripts
- Researcher adds context and checks for blind spots
- Writer creates 2 divergent drafts per post
- Synthesizer merges the best elements
- Reviewer runs quality checks and can cut weak posts
You review the final drafts and approve, edit, or reject each one.
Your edits automatically improve future runs.
Which mode would you like for next time?
If they choose autonomous, update the skill's configuration to default to
autonomous mode with a flag they can override.
Important Design Principles
Self-Contained
The output skill must work with ZERO other skills installed. Everything is
inline or in the skill's own references/ directory.
Voice Authenticity Over Volume
A factory that produces 3 posts the user actually publishes is better than
8 posts they delete. Quality gates matter more than output quantity.
Feedback Loop Is the Engine
The factory improves by learning from the user's edits. Every edit is a
calibration signal. The harvest-feedback logic (built into the skill)
processes edits between runs and updates voice profiles, workshop examples,
and lesson files.
Source Fidelity
Never fabricate details, quotes, or numbers. Every post must trace back to
a real conversation, event, or data point. If a claim can't be sourced,
cut it.
The User's Voice, Not Yours
The LLM's job is to disappear. If a reader can tell an AI wrote the post,
it failed. Voice fingerprints, lowercase openers, imperfect punctuation,
personal quirks — these are features, not bugs.