Bỏ qua để đến nội dung

07 — GitHub Content Team Flow

Nội dung này hiện chưa có sẵn bằng ngôn ngữ của bạn.

This is the writer-side of the content + design split. The writer drafts in Claude, asks the worker to commit the markdown to GitHub, then hands off to the design team via a frontmatter status flag — they don’t touch WordPress directly.

Content writer

Write a 700-word post about “Ceramic Coating Explained — what it is, how it works, and whether it’s worth it”. Niche is auto detailing. Tone: practical, no marketing fluff. Include a TL;DR up top and an FAQ section at the end.

Push it to GitHub for the design team: site viper-template, path viper-template/posts/ceramic-coating-explained.md, status ready-for-design, tags ceramic-coating, paint-protection, detailing-basics.

Claude
save_md_to_github

Drafted and pushed. The file landed at:

  • Repo: supportsn/seo-navigator-content
  • Path: viper-template/posts/ceramic-coating-explained.md
  • SHA: 5e40866a (returned by the worker; the design team can pass this back via sha for optimistic-concurrency on updates)
  • Commit URL: https://github.com/supportsn/seo-navigator-content/blob/main/viper-template/posts/ceramic-coating-explained.md

Frontmatter includes status: ready-for-design so the design team can pick it up with list_md_from_github(status="ready-for-design"). Body is 712 words — TL;DR, four sections, FAQ.

The worker validates that every file has at least slug and title in YAML frontmatter. The recommended shape for the content+design handoff:

---
slug: ceramic-coating-explained
title: "Ceramic Coating Explained: What It Is, How It Works, and Whether It's Worth It"
type: post
status: ready-for-design # the workflow flag — design team filters on this
author: contentwriter@seonavigator.online
created_at: 2026-05-26
tags: [ceramic-coating, paint-protection, detailing-basics]
categories: [auto-detailing]
target_keyword: "ceramic coating"
suggested_target_sites: [viper-template]
---

Status is a freeform string — the worker doesn’t enforce a state machine, so you can use whatever workflow naming works for your team (draft, editing, ready-for-design, deployed, archived, …).

The new file is visible immediately on GitHub:

GitHub content repo with markdown files

The MCP call also lands in the worker audit log with the actor (the content writer’s user account) and the target repo path:

Audit log entry for save_md_to_github

If two writers push the same path at the same time, the second call returns E_SHA_MISMATCH — they need to re-read the file (read_md_from_github), merge their changes manually, and push again. Same flow as a normal git edit conflict, just over MCP.

Demonstrate the content-team half of the GitHub-backed editorial workflow: write in markdown, push to a content repo, set status so the design team can pick it up (scenario 08).

  • Connector working (scenario 01).
  • The GitHub App is installed on the org/repo that backs the content team (e.g. acme-org/blog-content).
  • The user has at least one site configured with a github_content source pointing at that repo.
  • Claude Desktop on a new conversation.
  • A browser tab open on https://github.com/acme-org/blog-content/tree/main/content (or wherever drafts live), showing the current file list for comparison.
  1. Action: In the composer, paste:

    I want to write a post titled “How we cut LCP by 40% on a Next.js blog”. 600 words, tone analytical, end with a CTA paragraph. Add frontmatter with status: ready-for-design, target_site: acme-blog, slug: cut-lcp-nextjs, author: trung@seonavigator.online, today’s date. Save it to GitHub.

    Press Enter. Expected: Claude streams the markdown body (with the requested frontmatter at the top), then calls save_md_to_github with { repo: "acme-org/blog-content", path: "content/cut-lcp-nextjs.md", content, commit_message }. Tool card resolves green. Recorder: open the tool card to show the path — viewers want to see the folder convention.

  2. Action: Wait for Claude’s reply. Expected: Claude returns { commit_sha, html_url } pointing at the new file on GitHub. Recorder: highlight the html_url link.

  3. Action: Click the html_url. Expected: GitHub opens the file at content/cut-lcp-nextjs.md. Frontmatter is visible at the top, body renders as markdown preview when GitHub auto-renders. Recorder: scroll once down the file so viewers see both frontmatter and body.

  4. Action: In Claude Desktop, type:

    Show me all markdown files in the content repo with status ready-for-design.

    Expected: Claude calls list_md_from_github with a filter, returns a table with the new file at the top. Recorder: capture the table; the status column should show ready-for-design for the new row.

  5. Action (optional, only if you want to demo an edit): Type:

    Bump the word count to about 800 by adding a section called “What we tried that didn’t work”. Save it back to the same file.

    Expected: Claude calls save_md_to_github again with the same path; tool card resolves; GitHub now shows a second commit on the file. Recorder: refresh the GitHub tab; the file’s commit history now has two rows.

  • GitHub repo shows the new file at the agreed path.
  • Frontmatter contains all requested keys: status, target_site, slug, author, date.
  • The MCP Audit log shows tools/call save_md_to_github rows for each save.
  • On GitHub, either:
    • Delete the file via the GitHub UI (since MCP can’t), or
    • Update the frontmatter to status: archived so it stops appearing in the design team’s queue.
  • If you only added test commits, you can leave them — they’re harmless.
  • GitHub App not installed on the repo: tool returns E_GITHUB_NOT_INSTALLED with a link to the install URL. Show the user clicking through and retrying.
  • Path already exists: by default save_md_to_github overwrites with a new commit. Show this and mention the mode: "create-only" option if your build supports it.
  • Invalid frontmatter (e.g. status: random-value not in the allowed enum): Claude may warn but the file is saved anyway because frontmatter validation lives in the design step. Show the warning surfacing in scenario 08.