skills/blog-taxonomy/SKILL.md
Extract, suggest, and sync tags and categories for blog posts across all major CMS platforms. Supports WordPress REST API, Shopify GraphQL, Ghost Content API, Strapi REST/GraphQL, and Sanity GROQ. Generates tag suggestions from content analysis (keyword frequency, heading extraction, semantic grouping), enforces minimum post-count thresholds to prevent thin tag archives, and syncs taxonomy via authenticated API calls. Use when user says "tags", "categories", "taxonomy", "tag suggestions", "sync tags", "WordPress tags", "Shopify tags".
npx skillsauth add agricidaniel/claude-blog blog-taxonomyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Manage tags, categories, and topic clusters across CMS platforms.
| Command | Purpose |
|---------|---------|
| /blog taxonomy suggest <file> | Extract candidate tags and categories from content |
| /blog taxonomy sync <cms> | Push taxonomy to CMS via authenticated API |
| /blog taxonomy audit [directory] | Check for thin tags, orphan tags, taxonomy bloat |
Read the target file and extract:
Scan the body text for high-frequency phrases:
Exclude common non-tag words: articles, prepositions, conjunctions, pronouns.
Group related candidates into clusters:
(frequency * 2) + (heading_presence * 5) + (emphasis * 1)## Tag Suggestions: [Post Title]
| Rank | Tag | Score | Source |
|------|-----|-------|--------|
| 1 | content-marketing | 18 | H2 + 6 mentions |
| 2 | seo-strategy | 14 | H3 + 4 mentions |
| 3 | keyword-research | 11 | 5 mentions + bold |
### Suggested Categories
- Primary: [best-fit category]
- Secondary: [optional second category]
| CMS | API Type | Auth Method | Tags Model | |-----|----------|-------------|------------| | WordPress | REST | Application Passwords (base64) | First-class entities with IDs | | Shopify | GraphQL (Admin API) | Admin API access token | String array on Article | | Ghost | REST (Admin API) | API key with JWT signing | First-class entities | | Strapi | REST or GraphQL | API token (Bearer) | User-defined content type | | Sanity | GROQ / Mutations | Project token (Bearer) | Document type |
List tags:
GET {CMS_URL}/wp-json/wp/v2/tags?per_page=100&search={keyword}
Authorization: Basic {base64(username:app_password)}
Create tag:
POST {CMS_URL}/wp-json/wp/v2/tags
Body: {"name": "Tag Name", "slug": "tag-name", "description": "Optional"}
List categories (hierarchical, supports parent field):
GET {CMS_URL}/wp-json/wp/v2/categories?per_page=100
Create category:
POST {CMS_URL}/wp-json/wp/v2/categories
Body: {"name": "Category", "slug": "category", "parent": 0}
Assign tags to post:
POST {CMS_URL}/wp-json/wp/v2/posts/{id}
Body: {"tags": [1, 2, 3], "categories": [4]}
Pagination: follow X-WP-TotalPages header for full listing.
Tags on Shopify are string arrays on the Article object, not first-class entities.
Update article tags (GraphQL Admin API):
mutation {
articleUpdate(id: "gid://shopify/Article/123", article: {
tags: ["tag-one", "tag-two", "tag-three"]
}) {
article { id tags }
userErrors { field message }
}
}
List all tags in use (GraphQL):
{
articles(first: 250) {
edges {
node { id title tags }
}
}
}
Auth header: X-Shopify-Access-Token: {token}
Note: REST API marked legacy Oct 2024. GraphQL required for new apps since Apr 2025.
List tags:
GET {CMS_URL}/ghost/api/admin/tags/?limit=all
Authorization: Ghost {jwt_token}
Create tag:
POST {CMS_URL}/ghost/api/admin/tags/
Body: {"tags": [{"name": "Tag Name", "slug": "tag-name"}]}
JWT generation: sign with admin API key (id:secret format), iat = now, exp = 5 min,
audience = /admin/.
Endpoint auto-generated from content types. Typical setup:
GET {CMS_URL}/api/tags?pagination[pageSize]=100
POST {CMS_URL}/api/tags
Body: {"data": {"name": "Tag Name", "slug": "tag-name"}}
Authorization: Bearer {api_token}
Strapi v4+ uses the data wrapper. Check your content type schema for field names.
Query tags (GROQ):
*[_type == "tag"] { _id, name, slug }
Create tag (Mutations API):
POST https://{project_id}.api.sanity.io/v2024-01-01/data/mutate/{dataset}
Body: {"mutations": [{"create": {"_type": "tag", "name": "Tag", "slug": {"current": "tag"}}}]}
Authorization: Bearer {token}
Scan all posts in the target directory (or fetch from CMS). Build a map:
| Check | Threshold | Action | |-------|-----------|--------| | Thin tag archives | < 5 posts per tag | Recommend noindex or merge | | Orphan tags | 0 posts | Recommend deletion | | Tag bloat | > 50 total tags | Recommend consolidation | | Category depth | > 3 levels | Recommend flattening | | Uncategorized posts | No category assigned | Assign to appropriate category | | Duplicate slugs | Same slug, different name | Merge into canonical version |
Group findings by priority:
## Taxonomy Audit: [Site/Directory]
**Total tags**: [n] | **Total categories**: [n]
**Healthy**: [n] | **Thin**: [n] | **Orphan**: [n]
### Critical Issues
- [orphan tags list]
### Recommendations
1. Merge [tag-a] and [tag-b] (same topic, [n] combined posts)
2. Delete orphan tags: [list]
3. Add noindex to tag archives with < 5 posts
| Variable | Purpose | Example | |----------|---------|---------| | CMS_TYPE | Platform identifier | wordpress, shopify, ghost, strapi, sanity | | CMS_URL | Base URL of the CMS | https://example.com | | CMS_API_KEY | Authentication credential | Application password, API token, or key |
These must be set in the shell environment. Never store credentials in files or
commit them to version control. The skill reads them via $CMS_TYPE, $CMS_URL,
and $CMS_API_KEY at runtime.
development
Scaffold and operate Claude Blog Brain, a source-cited Obsidian brain for blog content creation, optimization, and management dual-optimized for Google rankings (E-E-A-T, the 2026 core updates) and AI citations (GEO/AEO), spanning writing, rewriting and freshness, SERP-informed briefs and outlines, editorial calendars and strategy, semantic topic clusters, schema and internal linking, multilingual publishing, the FLOW framework, factchecking, personas, distribution, and the blog delivery contract, grounded in the claude-blog skill. Use when the user says "claude-blog-brain", "Claude Blog Brain", "create a blog content creation, optimization, and management dual-optimized for Google rankings (E-E-A-T, the 2026 core updates) and AI citations (GEO/AEO), spanning writing, rewriting and freshness, SERP-informed briefs and outlines, editorial calendars and strategy, semantic topic clusters, schema and internal linking, multilingual publishing, the FLOW framework, factchecking, personas, distribution, and the blog delivery contract, grounded in the claude-blog skill brain", "import sources", "synthesize plan", "render report", or wants a persistent vault-backed operating system for blog content creation, optimization, and management dual-optimized for Google rankings (E-E-A-T, the 2026 core updates) and AI citations (GEO/AEO), spanning writing, rewriting and freshness, SERP-informed briefs and outlines, editorial calendars and strategy, semantic topic clusters, schema and internal linking, multilingual publishing, the FLOW framework, factchecking, personas, distribution, and the blog delivery contract, grounded in the claude-blog skill.
development
Research what people are actually saying about a topic in the last 30 days across Reddit, X / Twitter, YouTube, Hacker News, dev.to, Medium, and other public discourse platforms. API-free; uses WebSearch with platform-targeted site operators plus recency filters. Produces DISCOURSE.md (a structured brief) and JSON output the writer can consume. Complements blog-researcher (which focuses on authority sources) with a recency-and-engagement lens. Use when user says "blog discourse", "discourse research", "what are people saying about", "research what people are saying", "voice of customer", "social listening", "30-day research", "trend research", "what's the discussion on", "real-time research", "practitioner discourse", "/blog discourse".
documentation
Establish durable brand and voice context for cross-skill consumption. Generates BRAND.md (audience, positioning, do/don't editorial rules, taboo phrases, competitor differentiation) and VOICE.md (existing persona JSON re-expressed as readable prose), both written to the project root. When present, all blog sub-skills auto-load these files before writing or reviewing. Pairs with blog-persona, which manages the structured persona JSON. Use when user says "blog brand", "create brand context", "brand voice doc", "BRAND.md", "VOICE.md", "establish editorial brand", "brand guidelines for blog".
testing
Translate existing blog posts into one or more target languages with SEO-optimized localization. Produces native-quality translations that preserve markdown structure, frontmatter, schema JSON-LD, image and chart embeds, and citation capsules. Localizes keywords, meta tags, numbers, dates, currencies, and quote styles per locale. Flags machine-translation artifacts for review. Run BEFORE blog-localize: this handles language conversion; localize handles cultural adaptation after translation completes. Use when user says "translate blog", "blog translate", "uebersetzen", "traduire", "traducir", "translate post", "blog auf Deutsch", "blog en espanol".