SEO/GEO content engine. Seed, cluster, roadmap, brief, write, and publish — turning keywords into live articles. Delivers a compounding pipeline of organic traffic and AI-citation-friendly content, month over month.
文档
PostKing · SEO
试用SEO/GEO content engine. Seed, cluster, roadmap, brief, write, and publish — turning keywords into live articles. Delivers a compounding pipeline of organic traffic and AI-citation-friendly content, month over month.
它能做什么
Run SEO / GEO from seed keywords to published, AI-citation-friendly articles using PostKing — seed, expand, cluster, roadmap, brief, write, and publish.
技能文档
SEO / GEO
An agentic pipeline that takes a brand from 3–10 seed keywords all the way to published, SEO / GEO-targeted blog articles using PostKing.
What is GEO?
GEO stands for Generative Engine Optimization — writing and structuring content so that AI assistants (Claude, ChatGPT, Perplexity, Gemini, Google AI Overviews) quote and cite it when answering user questions.
Classic SEO optimizes for click-through from a search-results page; success is measured as rank position and CTR. GEO optimizes for being included as a cited source inside an AI-generated answer; success is measured as citation rate in AI responses. The end user may never click — being the quoted authority is the win. Both still matter: SEO drives discovery surfaces that index your content, and GEO determines whether that content survives extraction into an AI answer.
GEO-friendly content follows formatting rules that LLM extractors prefer:
- Definition-first paragraphs — the first 1–2 sentences under each H2 answer the heading as a standalone, quotable claim.
- Headings as questions or definitive statements, not clever wordplay, so hierarchy maps cleanly to extractable Q&A.
- FAQ blocks with explicit Q→A structure (
/or `` + paragraph). Highest-yield GEO format. - Source-attributable claims — concrete numbers, named studies, dated stats, primary sources cited inline.
- Schema markup (Article, FAQPage, HowTo) as JSON-LD so crawlers parse intent unambiguously.
- Self-contained sections — each H2 makes sense without scrolling up; LLMs extract sections out of context.
- Comparison tables and lists — easy for LLMs to lift verbatim.
- Authority signals in-prose — founding dates, sample sizes, first-person expert framing.
PostKing's SEO / GEO pipeline produces content optimized for both — keyword-target SEO with GEO-friendly structure (definition-first paragraphs, FAQ blocks, source-attributable claims) baked in by default.
When to Use
Use this skill when a user wants to grow organic/AI-citation traffic from keywords: seeding a topic list, clustering keywords into topical hubs, generating a content roadmap, drafting briefs, writing SEO/GEO-structured articles, or publishing/scheduling them. Also use it for post-publish audit work (gap analysis, competitor content diff) and for generating cluster-linked side pages or standalone comparison pages.
When NOT to Use
Not for one-off social posts, blogs without a keyword/cluster angle, or general brand content — route those to the postking-social/postking skill instead. Not for discovering or registering competitor domains — that's the postking-competitor-intel skill (though its output feeds this one). Not for full multi-channel campaign planning — that's postking-storylines.
Minimal tool subset
This skill needs 15 tools out of PostKing's 200+:
seo_add_seeds— register seed keywords.seo_generate_keywords— expand seeds into a full keyword set (async).seo_categorize— tag keywords by search intent (per-keywordupdatesarray, built fromseo_list_keywordsIDs).seo_generate_clusters— group keywords into topic-pillar clusters (async).seo_list_clusters— list clusters.seo_bulk_approve_clusters— approve clusters to unlock brief generation.seo_generate_roadmap— build prioritized article topics from an approved cluster.seo_list_briefs— list generated briefs.seo_get_brief— inspect one brief.seo_edit_brief— structured edit of a brief (fullbriefDatareplacement and/or status flip).seo_approve_briefs— approve briefs, unlocking article writing.seo_write_article— draft an article from an approved brief.seo_list_results— list generated articles.seo_publish_article— publish or schedule.get_job— poll any async operation.
Granular & optional operations — use these to drive a single step in isolation (e.g. you already have a keyword list and want to skip to clustering) or for post-publish/competitive work, rather than running the full pipeline:
seo_list_keywords— list the brand's scored keyword set (keyword, volume, KD, intent).seo_get_market_settings/seo_set_market_settings— read/configure the (location, language) SEO markets keyword research draws from; prerequisite for a language-scopedseo_generate_keywordscall (see step 2).seo_estimate_research_cost— read-only cost +pairCountpreview for one language before running a language-scoped pull.seo_gap— gap analysis: high-value topics not yet covered.seo_competitor— competitor content diff against a domain.seo_auto_assign_cta— batch-assign a published side-page CTA to blogs.seo_generate_side_page— generate a side page linked to an SEO cluster for topical authority.create_comparison_page— generate a standalone comparison/alternatives page.
Prerequisites
- Authenticated with credits — see the
postking-getting-startedskill. - A brand already onboarded — see the
postking-getting-startedskill. - Optional: competitors registered for competitor-aware clustering — see the
postking-competitor-intelskill.
Procedure
"Run the SEO / GEO flow for my brand. Seeds: 'AI content generation', 'social scheduling', 'brand voice'."
Async tools return { operationId, status } immediately — poll get_job({ operationId }) until state is completed, failed, partially_failed, or cancelled.
-
Seed.
seo_add_seeds({ brandId, seeds: ["AI content generation", "social scheduling", "brand voice"] }). -
Expand.
seo_generate_keywords({ brandId })→ async, pollget_job. Expands seeds into ~100 scored keywords against the brand's default market (Global = a single US/en pull) unless markets are configured otherwise.Multi-market / language-scoped research (optional). Only needed to scope a pull to one specific language, or once the brand's SEO markets already span more than one language (a Pro/Enterprise-tier capability). Flow:
seo_get_market_settings({ brandId })to see what's configured →seo_set_market_settings({ brandId, markets })to set 1–3 curated(locationCode, languageCode)pairs (curated set today: Germany 2276/"de", France 2250/"fr", Spain 2724/"es", Brazil 2076/"pt", US 2840/"en"; or passmarkets: "global"to revert to the US/en default) →seo_estimate_research_cost({ brandId, language })to seepairCountandestimatedCostUsdfor that language →seo_generate_keywords({ brandId, language })scoped to it.seo_get_market_settings/seo_set_market_settingsrequire a paid plan — a free/trial key gets a payment-required error. See Pitfalls for what happens if this ordering is skipped. -
Categorize. There's no brand-wide categorize call — build a per-keyword
updatesarray first. Callseo_list_keywords({ brandId })to get keyword IDs, thenseo_categorize({ brandId, updates: [{ keywordId, intent, userTags? }, ...] })—updatesis required (min 1, max 500 entries), each entry is{keywordId, intent?, userTags?}withintent∈ informational | commercial | navigational | transactional. Informational-intent keywords are prime GEO targets — they're the questions users ask AI assistants directly. -
Cluster.
seo_generate_clusters({ brandId })→ async, pollget_job. Groups keywords into topic-pillar clusters. Cluster pillars become topic-authority hubs that AI engines cite back to. If competitors are registered on the brand, this step automatically classifies each cluster'sproductFitand flags competitor-dominated clusters.Competitor-aware clustering. If the brand has competitors registered first (via the
postking-competitor-intelskill),seo_generate_clustersautomatically injects a "Registered competitors" block into the cluster-labeling step — no separate tool call, it's automatic once competitors exist. For each cluster the labeler then returns:clusterMeta.productFit:"core","adjacent", or"out_of_scope".clusterMeta.archetype: "competitor"(only when the cluster's keywords are dominated by a known rival brand), plusdetectedCompetitorand a pre-built "conquest" brief plan (review article + head-to-head comparison + alternatives listicle, optionally a pricing blog) instead of the generic hub-and-spoke plan.- Inspect these via
seo_list_clusters({ brandId, detail: "medium" })or"full"—clusterMeta.productFit/archetypeonly surface atmedium/fulldetail, notshort. - When you
seo_bulk_approve_clustersaarchetype: "competitor"cluster, it produces the conquest-plan briefs rather than generic ones. - Register competitors first with the
postking-competitor-intelskill.
Manual cluster (optional). To hand-create a named cluster instead of waiting on the auto-clustering pipeline, call
seo_create_cluster({ brandId, name, pillarKeyword?, description? })— no LLM call, starts empty, and is created alreadyapproved(skip step 6 for it). Names must be unique per brand; a duplicate returnscluster_name_taken. Add its first brief withseo_create_custom_brief(see the one-off-brief callout under step 6) passing this cluster'sidasclusterId. -
Review clusters.
seo_list_clusters({ brandId, detail: "medium" })— surface clusters with pillar keyword, keyword count, and top keywords (use"full"for raw data;clusterMeta.productFit/archetypeonly surface atmedium/full). Ask the user which to target, or pick by size/volume. -
Approve.
seo_bulk_approve_clusters({ clusterIds: [...] })(orseo_approve_clusterfor a single one; reverse withseo_reject_cluster/seo_bulk_reject_clusters). Approval is the gate — only approved clusters get briefs drafted, and this fires an async brief-generation job per cluster.One-off brief (optional, skips roadmap). To draft a single custom brief without running
seo_generate_roadmapfirst — e.g. a specific pillar keyword the user names outright — callseo_create_custom_brief({ brandId, pillarKeyword, type, supportingKeywords?, intent?, research?, selectedCompetitors?, clusterId? })(type∈ blog | comparison | tool | landing; async, pollget_job). Pass an existingclusterId(fromseo_create_clusterorseo_list_clusters) to file it under a named cluster, or omit it to auto-mint a throwaway single-brief cluster (origin: "manual"). The resulting brief lands inpending_reviewjust like a roadmap-generated one — continue at step 8. -
Roadmap.
seo_generate_roadmap({ clusterId })— produces prioritized article topics from the approved cluster. Each roadmap item gets a brief auto-drafted in the background, specifying FAQ blocks and definition-first headings to drive the GEO format. -
Review & edit briefs.
seo_list_briefs({ brandId, status: "pending_review" })→seo_get_brief({ briefId })to inspect. Refine withseo_edit_brief({ briefId, briefData })— pull the currentbriefDatafromseo_get_brief, mutate the outline (H2s, FAQs, keyword targets, etc.) locally, and send the full replacement back; there is no free-textinstructionsparam — or rebuild from scratch withseo_regenerate_brief({ briefId })(async). Brief approval is where you lock in the FAQ blocks and definition-first H2 structure — the article writer treats the approvedbriefDataas a contract. -
Approve briefs.
seo_approve_briefs({ briefIds: [...] })— unlocks article writing. -
Write.
seo_write_article({ roadmapItemId })— drafts an article from a roadmap item whose brief is approved. Repeat per item. Articles ship with FAQ schema and definition-first H2 paragraphs by default. -
Review results.
seo_list_results({ brandId })— list generated articles and their status. -
Publish.
seo_publish_article({ articleId, publicationId, schedule })— publish, or schedule for later. This is the free-tier choke point. -
Audit (optional).
seo_gap({ brandId })— uncovered high-value topics.seo_competitor({ brandId, domain })— competitor content diff. -
Auto-assign CTAs (optional, post-publish).
seo_auto_assign_cta({ blogIds: "all" })(or a 1–50 array) — batch-assigns a published side-page CTA to each blog. Skips blogs that already have a CTA and Webflow-synced blogs by default; pass overwrite/include-webflow flags to change that. Hard cap of 50 blogs per call. -
Cluster-linked side pages / comparison pages (optional).
seo_generate_side_page({ slug, key, clusterId })—slugis the parent landing page's slug; generates a side page under it, linked to an SEO cluster, strengthening the cluster's topical authority: it expands covered subtopics, feeding the citation patterns AI engines use when answering questions in that domain.create_comparison_page({ ... })generates a standalone comparison/alternatives page. Auto-assigned CTAs increase conversion yield without changing the article's GEO-friendly structure.
Cluster / keyword / roadmap housekeeping (optional)
These are correction/cleanup tools, not steps in the main pipeline — reach for them when the auto-generated set needs fixing rather than running the numbered Procedure again.
Cluster housekeeping (approve/reject/bulk-approve/bulk-reject are already in the main flow at step 6):
seo_edit_cluster({ clusterId, name?, pillarKeyword?, description?, keywordsMeta?, contentMix?, briefAssignments? })— rename/redescribe, or change membership.keywordsMetais a full-REPLACEMENT array, not a delta — fetch the current array viaseo_list_clusters({ detail: "full" }), mutate it, and send the whole thing back (see Pitfalls).seo_delete_cluster({ clusterId, confirm: true })— hard delete; cascades to the cluster's roadmap items and their briefs. Not undoable — preferseo_reject_cluster(reversible viaseo_restore_cluster) unless the cascade is actually wanted.seo_merge_clusters({ clusterId, sourceClusterId })— reassigns the source cluster's keywords, roadmap items (and their briefs), and linked blog articles onto the targetclusterId, then deletes the source. Not undoable. The target's ownkeywordsMetaisn't updated by the merge — follow up withseo_edit_clusterif it needs to include the newly reassigned keywords.seo_restore_cluster({ clusterId })— undoseo_reject_cluster, back topending_review.seo_unapprove_cluster({ clusterId })— revertapproved→pending_review. Fails once briefs already exist for the cluster.
Keyword housekeeping:
seo_edit_keyword({ keywordId, intent?, userTags?, priority?, excludedFromClustering? })— override intent/tags/priority for one keyword, or hold it out of the next clustering pass. At least one field required.seo_bulk_edit_keywords({ keywordIds, intent?, userTags?, priority?, excludedFromClustering?, confirm: true })— same, across many IDs in one call.seo_delete_keyword({ keywordId, confirm: true })/seo_bulk_delete_keywords({ keywordIds, confirm: true })— soft-delete (setsdeletedAt; filtered out of every query, but recoverable).seo_restore_keyword({ keywordIds })— undo a soft-delete. IDs that aren't currently deleted are silent no-ops.seo_list_keyword_ids({ ...same filters as seo_list_keywords, e.g. relevanceMax, hasTag })— unpaginated ID export, no keyword data attached. Feed the result straight into the two bulk tools above.seo_tag_geography({ dryRun?, retag? })— unrelated to SEO market/language settings despite the similarly-general name: async, classifies each keyword's geographic search intent and writes ageo:*userTag (geo:us-mn,geo:us,geo:none,geo:ambiguous). RundryRun: truefirst to reviewtagCounts/ambiguousKeywordsbefore committing (idempotent by default — already-tagged keywords are skipped unlessretag: true). Then select withseo_list_keywords/seo_list_keyword_idsviahasTag.
Roadmap surface — seo_generate_roadmap (step 7 in the Procedure) is the only generation entry point; everything below is read/edit/delete on items it already created:
seo_list_roadmap({ status?, detail? })— list items;status∈ suggested/in_progress/completed/ignored.seo_roadmap_get({ itemId, detail? })— single item, full detail by default.seo_roadmap_edit({ itemId, title?, status?, priority? })— rename, re-status, or re-prioritize.seo_roadmap_delete({ itemId, confirm: true })— permanent delete, irreversible.seo_roadmap_stats({ brandId? })— completed/in-progress/suggested counts, plus a dashboard link.get_seo_roadmap({ status?, detail? })— a legacy duplicate, registered inblog.tsrather thanseo/roadmap.ts: it combinesseo_list_roadmap+seo_roadmap_statsinto one call with a slightly different item shape (flattype/keywordfields instead ofprimaryKeywords). Prefer the two split tools above; only reach for this one if an existing integration already depends on its response shape.
CLI fast path
If a shell is available, the same flow via pking:
pking seo seeds "AI content generation" "social scheduling" "brand voice"
pking seo generate # expand seeds (long-running)
pking seo categorize
pking seo cluster
pking seo clusters list
pking seo clusters approve
pking seo clusters bulk-approve
pking seo briefs generate --cluster [--cluster ...] # generates the roadmap + briefs (L3) for approved cluster(s)
pking seo roadmap [--cluster ] # READ-ONLY: lists roadmap items, optionally filtered by cluster
pking seo briefs list [--status pending_review]
pking seo briefs view
pking seo briefs regenerate
pking seo briefs approve
pking seo briefs bulk-approve
pking seo write [--hero-image] [--voice ] [--no-wait] [--json]
pking seo gap
pking seo competitor --domain
pking seo publish --article-id [--publication ] [--schedule ]
pking seo stats
CTA auto-assignment is MCP/dashboard-only — there is no pking blogs auto-assign-cta command. Use the seo_auto_assign_cta({ blogIds }) MCP tool instead (blogIds is an array of up to 50 blog IDs, or the literal "all").
Brief edits (seo_edit_brief's structured briefData replacement) have no CLI command — do them via the MCP tool or the PostKing dashboard's brief editor. pking seo roadmap edit supports only --action and --status (no --title/--priority). pking seo clusters approve and pking seo briefs approve each take a single id — use bulk-approve/bulk-reject (clusters) for multiple ids at once.
CLI-only granular operations (no direct MCP tool equivalent — useful when composing your own pipeline):
- List scored keywords:
pking seo keywords list --json— the full scored keyword list (keyword, volume, KD, intent). Pipe a filtered subset into CSV clustering below. - Cluster from a CSV:
pking seo clusters generate --csv keywords.csv --brand(or--brandalone to use the brand's existing keywords). Async — the CLI polls automatically and prints{clustersCreated, clustersMerged, keywordsAssigned}; pass--no-waitfor anoperationIdand poll manually withpking jobs list. CSV needs a header row with a requiredkeywordcolumn; optionalvolume,kd,intentcolumns improve cluster quality:
Other flags:keyword,volume,kd,intent ai content generation,8100,42,informational seo content tool,2400,38,commercial--target-size,--no-cannibal-check(skip dedup check),--json(full cluster objects). - Generate a single brief from agent-supplied data:
pking seo briefs generate-one --pillar "ai content generation" --supporting "ai blog writer,seo content tool" --type blog --research advanced --brand --json— produces one content brief without a roadmap, from data you supply directly. Async, polls and prints the fullbriefDataJSON. Required:--pillar,--supporting(comma-list, no spaces),--type blog|comparison|tool|landing,--brand. Optional:--intent,--research advanced|fast(defaultadvanced;fastskips external research),--tier hub|spoke|side_page,--json,--no-wait. The returnedbriefDatais the same structure accepted byseo_edit_brief'sbriefDataparam.
Expected Output
- A populated content roadmap tied to keyword clusters.
- Draft articles scored against primary keywords, each with FAQ/definition-first GEO structure.
- A gap-analysis report listing uncovered high-value topics (if run).
- At least one published or scheduled article (if credits + free tier allow).
Pitfalls
INSUFFICIENT_CREDITS— surface thecheckoutUrlfrom the error envelope and stop, or hand off to thepostking-getting-startedskill's billing section (billing_list_packs→billing_topup).FREE_CAP_REACHEDonseo_publish_article— same treatment asINSUFFICIENT_CREDITS.RATE_LIMITED— back off using theretryAftervalue from the error envelope before retrying.UNAUTHORIZED— re-run the login flow described in thepostking-getting-startedskill.clusterMetamissing/empty on a cluster — either no competitors are registered on the brand yet (see thepostking-competitor-intelskill), or the cluster simply doesn't overlap a known rival's keyword footprint (expected for purely core/adjacent clusters).seo_generate_keywords({ language })pointed at a language with no configured SEO market fails the async job (check viaget_job) with[keyword-pull] brand has no configured SEO market for language ""— callseo_set_market_settingsfirst (seo_estimate_research_costwill have shownpairCount: 0for that language). Omittinglanguageentirely on a brand whose markets already span more than one language fails the same way with... has markets spanning N languages ... a keyword pull must specify opts.languageCode— passlanguageexplicitly in that case.seo_edit_cluster'skeywordsMetais a full REPLACEMENT array, not a delta — sending a partial list silently drops the missing members from the cluster. Fetch the current array viaseo_list_clusters({ detail: "full" }), mutate it, then send the whole thing back.- Calling
seo_edit_briefwith a free-textinstructionsparam — it's silently ignored; the inner route only acceptsbriefData(structured) and/orstatus. seo_generate_side_pagerejects aparentSlugparam name — the tool expectsslugfor the parent landing page.pking lp side generate --typeis currently broken — the inner route ignores the `` path param and requiresname/slug/landingPageIdin the request body, so it always 400s. Use the MCP toolgenerate_side_page({ slug, key, sidePageType })instead (sidePageType∈landing|text|comparison).
Verification
seo_list_clusters({ brandId, detail: "short" })should return without error and reflect any clusters just created.seo_list_briefs({ brandId })should list briefs whose count matches the roadmap items just generated.seo_list_results({ brandId })should show the article afterseo_write_articlecompletes.
相关技能
Optimize any website for SEO and GEO (AI search engines) — keyword strategy and clustering, site architecture and multilingual URL structure, page-level on-page SEO, AI-citation-ready content, topical-authority planning, internal linking, and structured-data schema
Publish blogs that build authority and traffic. Generate, refine, and ship articles PostKing-hosted or pushed to WordPress, Medium, or Substack. Delivers a steady stream of SEO-ready articles without the writer's block.
SERP-based semantic topic clustering for content architecture planning. Groups keywords by actual Google SERP overlap (not text similarity), designs hub-and-spoke content clusters with internal link matrices, and generates interactive visualizations. Optionally executes content creation if claude-blog is installed. Use when user says "topic cluster", "content cluster", "semantic clustering", "pillar page", "hub and spoke", "content architecture", "keyword grouping", or "cluster plan".
Generate a complete AI-GEO (Generative Engine Optimization) marketing plan for a client and deliver it as two artifacts: a Word document (the presenter's teleprompter, full detail) and a minimal display-only PPTX (10-12 slides, lots of white space, one core point per slide). Works in two input modes — detailed mode when the user supplies target keywords and/or a source plan, and light mode when the user supplies only a company website or basic company info, in which case the agent self-researches the industry and auto-generates about 10 core GEO demand keywords before proceeding. Use when a user asks to make or redo a GEO marketing plan, an AI 搜索优化方案, a 生成式引擎优化方案, or wants a client-ready Word plus PPT for GEO, especially built on the 360 智见 (360 Zhijian) GEO methodology.
Router skill for PostKing — confirms the active brand, then hands off to the right specialist skill for posts, blogs, landing pages, SEO, or setup.