This is the exact system I run to turn a call transcript into a published blog post automatically, written to get found by AI search and cited by the machines. It writes itself, links itself, and ships itself to my site. Copy it. Fill it in. Run it.
You hold the approval gate in the middle. That's the whole system on a whiteboard. Picture it before you touch a single file. This loop is one worker inside a broader AI operating system for your business, and it earns its keep because turning one transcript into published content is how you grow an audience as a solopreneur.
Reads a transcript. Writes a full AEO blog post in your voice. Links it to your existing posts. Parks it in your Content Library as a Draft. It writes. It does not publish.
Grabs your approved drafts. Generates the publish prompt. Ships them live to your site. Updates Notion to Published. It ships. It does not write.
You already duplicated the Notion setup, so you have the databases. This gets the routines running on top of them. You don't fill in the blanks by hand. Your Claude does.
Each skill file has a SETUP block at the top with bracketed values like [YOUR_DOMAIN] and [CONTENT_LIBRARY_ID]. Open Claude chat with your Notion connected, paste both skill files, and paste this:
I'm setting up two Claude Code routines from these skill files. Search my Notion for my Content Library and Transcript Inbox database IDs and my name, fill those in. Then ask me for anything you can't find in Notion. Output both files fully filled in and ready to drop into Claude Code.
Claude finds the Notion values on its own. Then it asks you for the few it can't find, because these live on your machine or in your head:
Answer those, and Claude hands you both files fully filled in.
Fills in the files. Searches Notion. Can't write to your machine.
Installs the files into your skills folder. Runs the routines.
One brain fills it in. The other installs it. Same two-brain split you already run.
Take the filled-in files and have Claude Code drop them into your personal skills folder so they work everywhere:
~/.claude/skills/content-creation-engine/SKILL.md ~/.claude/skills/blog-post-publisher/SKILL.md
Folder name = skill name. The file inside is named SKILL.md.
In the Claude desktop app, go to the Code tab → Scheduled Tasks (the clock icon). Create two. Prompts are in the Scheduled Tasks section below.
Do not arm both routines and walk away on day one. Run each one manually first.
Trust is earned by clean runs, not by the build being done.
Copy this whole block into a file named SKILL.md inside ~/.claude/skills/content-creation-engine/. This is the routine that writes.
---
name: content-creation-engine
description: Turn a transcript into an AEO-optimized blog post draft and park it in the Content Library as a Draft. Use this skill whenever you say "run the engine," "create content," "blog post from this transcript," or drop a transcript and want a publish-ready draft produced from it. This is the CREATE half of the two-routine system. It writes. It does not publish.
---
# Content Creation Engine
Turn one transcript into one AEO-optimized blog post draft, written in your voice, parked in your Content Library as a Draft, ready for the Auto-Publisher to ship.
This is the first of two routines. This one CREATES. The Auto-Publisher SHIPS. Keep them separate. One job each.
# ============================================================
# SETUP: FILL IN YOUR WORLD (do this once, then delete this block)
# ============================================================
# [YOUR_NAME] = your name (author + voice)
# [YOUR_DOMAIN] = yoursite.com
# [CONTENT_LIBRARY_ID] = your Notion Content Library database ID
# [TRANSCRIPT_SOURCE_ID] = your Notion Transcript Inbox database ID
# [NEWSLETTER_URL] = yoursite.com/newsletter (or your opt-in)
# [BRAND_YELLOW] = your accent hex (e.g. #FFE307)
# ============================================================
## What This Skill Does
1. Reads a transcript (pasted, or pulled from your Transcript Inbox in Notion)
2. Extracts the strongest teaching nugget
3. Writes a full AEO-optimized blog post in your voice
4. Adds outbound internal links to your existing posts (post is fully linked before it ships)
5. Saves it to your Content Library with Status = Draft
It stops there. It does not publish. That is the second routine's job.
## Inputs
One of these:
- A transcript pasted into chat
- A transcript pulled from your Transcript Inbox database ([TRANSCRIPT_SOURCE_ID])
- A raw idea or teaching moment described in conversation
If you say "pull my latest transcript," search Notion for the most recent entry in the Transcript Inbox.
## Workflow
### Step 1: Extract the Gold
Read the full transcript. Pull out:
- Teaching moments where a concept gets explained
- Quotable lines (exact words, not paraphrased)
- Frameworks or mental models shared
- Questions asked that others in your audience are also asking
- Breakthrough moments or mindset shifts
- Stories and analogies used to simplify something complex
ANONYMIZATION RULE (non-negotiable): If the transcript is a client call, NEVER use client names, company names, or identifying details. Replace with generic stand-ins ("a founder I work with"). If you need industry context, use a different industry than the real one.
Present the top 3-5 nuggets ranked by content potential. Recommend the strongest. Wait for confirmation before writing. In an unattended routine run, default to the top-ranked nugget and note which one you chose.
### Step 2: Write the AEO Blog Post (1,000-2,000 words)
AEO = Answer Engine Optimization. Written for humans AND AI search engines.
Required structure:
1. Title (H1) with the primary keyword in it
2. TL;DR block at the top (3-4 bullets)
3. Intro: keyphrase-rich first paragraph, then a personal story as evidence in paragraph two
4. Question-based H2 sections (headers phrased as questions people search). These become the answers AI engines pull.
5. Personal stories woven throughout (lived experience is the credibility)
6. Actionable steps the reader can use today
7. Strong close that lands the message
8. CTA section ("Ready to Go Deeper?" pointing to your chosen offer)
### Step 3: Add Outbound Internal Links (BEFORE it becomes a draft)
Link the post while you write it, not after it publishes.
- Find 3-5 existing published posts that genuinely connect to this topic
- Add inline links in the body with natural conversational anchor text
- Live URLs only ([YOUR_DOMAIN]/blog/[slug])
- Record them in the draft notes as internal_links_included: [list] so the Auto-Publisher can verify them
Never force a link. If only 2-3 natural fits exist, that is fine.
### Step 4: Save to Content Library as Draft
Write the post to Notion. Content Library database ID: [CONTENT_LIBRARY_ID]
Properties:
- Title: the post title
- Status: "Draft"
- Type: "Article"
- Source: "Transcript"
- Meta description: under 160 chars, in the Notes field
- internal_links_included: the outbound links you added, in the Notes field
## Voice Rules
Write so the reader would believe [YOUR_NAME] wrote every word.
- Short to medium sentences. Heavy line breaks. One-sentence paragraphs for emphasis.
- Talk TO the reader with "you" constantly.
- Open with a bold statement or drop them straight into a story. No preamble.
- Lived experience, not theory. Stories carry the credibility.
### NEVER Do This
- Never use: delve, unlock, craft, foster, tapestry, embarking, unleash, unveil, realm, boasts, revolutionize, tenets
- Never use semicolons
- Never use em dashes
- Never use contrastive framing ("This isn't X, it's Y")
- Never use tension-based setups or dramatic juxtaposition
- Never start an idea through negation
- Never start a sentence with "And"
- Never use "Here's the truth" / "Here's the thing" as a sentence starter
- Never write without a clear takeaway or action for the reader
- Never hide behind complexity. Always simplify.
## Quality Gate
Every draft must pass before it saves:
1. Would you post this under your name without editing?
2. Does it sound like YOU, not like AI wrote it?
3. Does the reader get full value from this single piece without context?
4. Is there a clear takeaway or action?
5. Does it come from lived experience, not theory?
6. Are the outbound internal links present in the body?
If any answer is no, rewrite before saving.
## ADVANCED: AEO Keyword Layer (optional, skip for v1)
Skip this entire section to get your loop running. Add it once the loop is boring and reliable. This is a power-up, not a prerequisite.
If you maintain a keyword database in Notion, wire it in here:
- Before writing, pull the target keyphrase for this topic cluster
- Make sure the keyphrase appears verbatim in the title, first paragraph, and at least one H2
- Tag the post with the cluster it belongs to
Without this layer, the post still gets written and still ranks on answer quality. Get transcript-to-published running first.
Copy this whole block into a file named SKILL.md inside ~/.claude/skills/blog-post-publisher/. This is the routine that ships. It assumes a code-based site: flat HTML files in a git repo, deployed by Cloudflare Pages or Vercel.
--- name: blog-post-publisher description: Publish an approved blog post from the Content Library to your website via Claude Code. Use this skill whenever you say "publish this post," "get this live," "push this to the site," or reference taking an approved draft and making it live. This is the SHIP half of the two-routine system. It does NOT write content. --- # Blog Post Publisher Takes an approved blog post from your Notion Content Library and produces everything needed to publish it on your website via Claude Code: the publishing prompt, the inbound linking instructions, and the post-publish Notion update. This is the second of two routines. The Content Creation Engine WROTE the post. This one SHIPS it. It does not write or edit content. # ============================================================ # SETUP: FILL IN YOUR WORLD (do this once, then delete this block) # ============================================================ # [YOUR_NAME] = your name (author byline) # [YOUR_DOMAIN] = yoursite.com # [CONTENT_LIBRARY_ID] = your Notion Content Library database ID # [BLOG_PATH] = where your blog HTML files live (e.g. site/blog/) # [OG_DEFAULT_IMAGE] = your default social image URL # [BRAND_YELLOW] = your accent hex (e.g. #FFE307) # [DEFAULT_CTA] = your default offer # ============================================================ ## What This Skill Does NOT Do - Does not write or edit content (the Content Creation Engine does that) - Does not add outbound internal links (those arrive in the draft, already written) - Does not execute Claude Code commands (you paste them into Claude Code) - Does not push code to the site (Claude Code deploys) - Does nothing after publish except update Notion status ## The Publishing Workflow ### Step 1: Identify the post If you name the post, find it in the Content Library. If you say "publish the blog post" without specifying, check the most recent Draft posts and confirm. Fetch the full content: text, meta description, primary keyword, and the internal_links_included note from the Notes field. ### Step 2: Verify the post is publish-ready Confirm these are present before generating the prompt: 1. Title (H1) with primary keyword 2. TL;DR block (3-4 bullets) 3. Intro (keyphrase-rich first paragraph, story as evidence in paragraph two) 4. Question-based H2 sections 5. Outbound internal links in the body (3-5, live URLs only, matching internal_links_included) 6. Actionable steps 7. Strong close 8. CTA section 9. Meta description (in Notes field) HARD RULE: If the outbound internal links are missing from the draft body, flag it and do NOT generate the publishing prompt. The post is not publish-ready. Linking happens at creation, never after publish. If anything else is missing, flag it. Do not fix content. Just flag what's missing. ### Step 3: Generate the Claude Code publishing prompt Create a downloadable markdown file with the complete Claude Code prompt: # CLAUDE CODE: Publish New Blog Post ## Instructions I want to publish a new blog post on my website. Create the HTML file matching my existing blog post template structure. File structure: My blog posts are flat .html files in the [BLOG_PATH] directory. Keep this same structure. Create the new post as [BLOG_PATH][slug].html. Clean URLs: My published URLs do NOT have .html at the end. The URL should be [YOUR_DOMAIN]/blog/[slug] with no extension. Look at how my existing posts handle this (Cloudflare Pages / Vercel config) and make this new post work the same way. Do NOT create a subfolder with index.html. Keep my blog directory flat. File path: [BLOG_PATH][slug].html Published URL: [YOUR_DOMAIN]/blog/[slug] (NO .html in the URL) Category: [category] Date: [publish date] Author: [YOUR_NAME] Meta description: [under 160 chars, from Notes field] AEO requirements: - Article schema markup (JSON-LD) with author, date, headline, description - FAQ schema for the H2 question headers in the post - TL;DR section styled as a summary callout box (light background, border-left accent using [BRAND_YELLOW]) - H2 headers as proper H2 tags for answer engine parsing - Preserve all internal links already in the post body exactly as written OG and social tags (default image, no human step): - og:image: [OG_DEFAULT_IMAGE] - og:image:width: 1200 - og:image:height: 630 - twitter:card: summary_large_image - twitter:image (same as og:image) - If a custom thumbnail exists for this post, use it instead of the default. Inbound internal links (same deploy as the new post): After creating the new post file, identify 2-3 existing blog posts where this new post's topic naturally connects. Add ONE inline link per existing post pointing to the new post's URL, with natural conversational anchor text. Rules: Max 1 link added per existing post. Max 3 existing posts edited. Never force a connection. Commit these edits in the SAME push as the new post file. Also: Add this post to the blog listing page as the first entry, matching the existing card format. IMPORTANT: The published URL must NOT have .html at the end. The file in the repo is .html but the browser URL must be clean. Then a content section with the full blog post content (including outbound internal links and CTA). Save as a downloadable file with create_file and present_files. ### Step 4: Post-publish Notion update When the post is confirmed live, update the Content Library entry ([CONTENT_LIBRARY_ID]): - Status: "Published" - Date Published: the publish date - URL: the live URL ([YOUR_DOMAIN]/blog/[slug]) ## Internal Linking Design Outbound links (new post to existing posts) are owned by the Content Creation Engine, written into the draft before it reaches this skill. Inbound links (existing posts to new post) are owned by this skill, added in the same deploy as the new post. The publisher verifies outbound links exist (Step 2) and instructs inbound links (Step 3). There is no post-publish linking step. ## URL Rules (Non-Negotiable) - Published URLs are always [YOUR_DOMAIN]/blog/[slug] with NO .html in the browser - Blog files are flat .html in [BLOG_PATH] - No subfolders with index.html. Keep the directory flat. - Slugs and image filenames: lowercase and hyphens only - Every Claude Code prompt must state: no .html in the URL, no subfolder structure ## Output Checklist - Outbound internal links confirmed present (3-5, live URLs only) - Claude Code prompt saved as downloadable file - Clean URL specified (no .html) - Flat file structure specified - Meta description included - All AEO schema requirements listed - OG/Twitter Card tags included - Inbound linking instructions included (same deploy, max 1 per post, max 3 posts) - Blog listing update instruction included - Default OG image tags included - Notion update plan ready for post-publish
Code tab → Scheduled Tasks (the clock icon). Create two. Each gets a schedule, a prompt, and a cap.
Run the content-creation-engine skill on the newest transcript in my Transcript Inbox. Write the blog post, link it, save it as a Draft in my Content Library. Process a maximum of 1 transcript per run.
Run the blog-post-publisher skill on any approved Draft blog posts in my Content Library. Generate the publish prompt and deploy. Update Notion status to Published with the live URL. Publish a maximum of 3 posts per run.
These are the rails that keep an unattended routine from going sideways. Build them in from day one.
"Max 1 transcript per run." "Max 3 posts per run." A routine with no cap can run away. Always cap it.
The create routine saves as Draft. The publish routine only ships posts you've approved. You decide what approved looks like, a status field, a checkbox, a tag. That gate is you. Keep it until the system has earned your trust over many clean runs.
The AEO keyword database is a power-up, not a prerequisite. The create skill writes and ranks on answer quality without it.
Run the loop. Make it boring. Then make it sharp.
You just got the full transcript-to-published machine. Inside Undeniable Studio, you build the next one live with me, wired to your business, your voice, your stack.
Join The Studio