Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, email [email protected] and we’ll put it right.

io.github.bitsandtea/postking-mcp

NPM · POSTKING-MCP · 2 COMPONENTS · SCANNED AUG 3

PostKing MCP server for managing brands, generating posts, scheduling content, and publishing blogs.

+21 this week 54 Trust /100
Trust breakdown (6 categories)

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score →

Supply Chain Security37
  • Malware scan not yet available for this package.Unverified
  • Only part of the dependency tree could be resolved (96 of 100), so this covers what we could see, not the whole tree.Partial
  • No install/post-install scripts declared.Pass
  • Only part of the dependency tree could be resolved (96 of 100), so this covers what we could see, not the whole tree. View diagnostics → Partial
Provenance & Transparency45
Schema Quality & AI Usability76
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (good).Pass
  • Context-footprint check failed: tool/resource definitions use about 32233 tokens (~146/item across 220 items; 220 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management27
  • Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage99
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 96% of tool parameters carry a description.Partial
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

Add this component to your MCP client. Where a client-specific snippet is available, pick your client below and copy it straight into your config; otherwise use the connection detail shown.

npm · postking-mcp

# add to Claude Code
claude mcp add bitsandtea-postking-mcp -- npx -y postking-mcp
# add to Codex CLI
codex mcp add bitsandtea-postking-mcp -- npx -y postking-mcp
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "bitsandtea-postking-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "postking-mcp"
      ],
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add bitsandtea-postking-mcp --command npx --arg -y --arg postking-mcp
# ~/.hermes/config.yaml
mcp_servers:
  bitsandtea-postking-mcp:
    command: "npx"
    args: ["-y", "postking-mcp"]
// mcp.json
{
  "mcpServers": {
    "bitsandtea-postking-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "postking-mcp"
      ]
    }
  }
}
Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 3 Aug 26 −3

    No change was recorded against any check on this day. Supply Chain Security went from 47 to 37. Other categories moved too: Stability & Change Management rose 4.

  • 2 Aug 26 +32
    • Provenance: unverified → fail security
    • Install scripts: unverified → pass security
    • Known CVEs: unverified → partial security
    • Schema quality: unverified → good functional
    • Stability: unverified → 0.23 functional
    • License: unverified → pass functional
    • Dependency health: unverified → partial functional
    • MCP protocol: unverified → pass functional
    • Maintenance: unverified → pass functional
    • Licence: MIT functional
  • 31 Jul 26 −8
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 27 Jul 26 33

    First indexed and scored.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 3 Aug 2026 · Analysed npm/[email protected]

Provenance none

Ecosystem: npm · Outcome: none

Dependencies 96 packages

96 packages in the resolved dependency tree · 96 deprecated · 29 stale.

The dependency tree was only partially resolved, so these counts may be incomplete.

MCP tools — 220 exposed · ~31,224 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability.

Tool Tokens
list_lp_versions ~123

List all saved versions of a landing page. Default detail='short'. Use view_lp_version to see section content.

NameTypeReqDescription
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…
slugstringyesLanding page slug

No output schema declared.

No examples provided.

list_operations ~297

To check a SPECIFIC operation's status, call get_job with its operationId — this list only returns the most recent ops and may omit a just-started one. List recent Operations (the newer async-op system) for the active brand. Each operation has: id, kind, state (pending|running|completed|partially_failed|failed|cancelled), progress, result, errors. Use get_job with an operationId to poll a specific one. Filters: kind (e.g. seo_keyword_generate, seo_cluster_generate, lp_generate), state. Supports detail param: short=id+kind+state, medium=adds scopeId+progress+timestamps (no result/errors), full=raw including result.

NameTypeReqDescription
brandIdstringBrand ID (uses active brand if omitted)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…
kindstringFilter by operation kind (e.g. seo_keyword_generate)
limitinteger
statestringFilter by state: pending | running | completed | partially_failed | failed | cancelled

No output schema declared.

No examples provided.

list_post_cards ~144

List the carousel cards attached to a post. Cards are used for LinkedIn carousel / PDF generation. Returns {index,title} by default; use detail='medium' for truncated body, 'full' for all fields.

NameTypeReqDescription
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…
postIdstringyesPost ID

No output schema declared.

No examples provided.

list_posts ~180

List recent posts and drafts. Filter by status or platform. Use status='created' to find unscheduled drafts. Returns id+status+scheduledAt by default; use detail='medium' or 'full' for more fields. For a single post use get_post.

NameTypeReqDescription
brandIdstringBrand ID (uses active brand if omitted)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…
limitnumber
platformstring
statusstring

No output schema declared.

No examples provided.

list_publications ~151

List all blog publications (the containers that blog articles live under). detail='short' returns id+name; detail='full' returns raw rows. Distinct from list_publishing_connections which lists external platforms like WordPress.

NameTypeReqDescription
brandIdstringBrand ID (uses active brand if omitted)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…

No output schema declared.

No examples provided.

list_publishing_connections ~56

List external publishing connections for a blog publication (WordPress, Medium, Substack, etc.).

NameTypeReqDescription
brandIdstringBrand ID (uses active brand if omitted)
publicationIdstringyesBlog publication ID

No output schema declared.

No examples provided.

list_side_pages ~131

List side pages attached to a landing page. Default detail='short'. Heavy JSONB (overrides/config) only at full via view_side_page.

NameTypeReqDescription
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…
slugstringyesParent landing page slug

No output schema declared.

No examples provided.

list_themes ~146

List all content themes for the active brand with their IDs. detail='short' (default) returns id+title; detail='medium' adds content preview; detail='full' returns raw content.

NameTypeReqDescription
brandIdstringBrand ID (uses active brand if omitted)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…

No output schema declared.

No examples provided.

list_voices ~112

List all available voice profiles with their IDs. Lists default short; pass detail=medium/full for more fields.

NameTypeReqDescription
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…

No output schema declared.

No examples provided.

login_complete ~40

Wait for the user to approve the PostKing login code in their browser and then save the token. Polls automatically; call this immediately after `login_start`.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

login_start ~91

Start the PostKing login flow. Returns a URL and short code for the user to visit in their browser. IMPORTANT: Immediately after this tool returns, show the URL + code to the user and then call `login_complete` — it will wait (polling in the background) until the user approves the request in their browser, so there is no need to ask the user to tell you when they are done.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

logout ~14

Clear locally stored PostKing credentials.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

onboard_brand ~121

STEP 1 of brand onboarding (website path). Crawls the site in the background and kicks off audience analysis + 10 themes. Sets the new brand as active and RETURNS a `nextStep` payload. IMMEDIATELY after this returns, ask the user which social platforms they publish on, then call `set_brand_mediums`. Do not call `get_onboarding_status` until mediums are set.

NameTypeReqDescription
namestringBrand name (inferred from site if omitted)
websiteUrlstringyesThe website to crawl and analyze

No output schema declared.

No examples provided.

pick_post_visual ~250

Select a visual for a post on a given platform. Use the chosen option's `pickArgs` from generate_post_visual_options VERBATIM — for card/quote templates that means passing kind + style + variant together; for a library/smart asset or a stock photo, pass the assetId or slot from its pickArgs. Do not invent style names. variant is a 1-based template variant index. Includes editInVisualEditor: a direct URL to edit the post in the visual editor (when active brand is set).

NameTypeReqDescription
assetIdstringLibrary asset ID from list_assets
kindstringVisual kind, taken verbatim from the chosen option's pickArgs. REQUIRED when picking a card or quote template style (e.g. kind:'quote' with style:'gradient-bold'). If omitted, the server assumes 'car…
platformstringyesTarget platform, e.g. 'linkedin'
postIdstringyesPost ID
slotstringInternal template slot key (advanced)
stylestringTemplate style name from generate_post_visual_options
variantintegerTemplate variant index

No output schema declared.

No examples provided.

preview_audience_edit ~138

Read-only helper. Call this BEFORE edit_audience to discover which `sections`/`subsections` values are valid for this brand. Pass the natural-language change you intend to make; returns the available sections/subsections (computed from the brand's current audience data) plus a preview. Use the returned section keys (e.g. 'demographics', 'painPoints', 'positioning') as the required `sections` array for edit_audience.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
promptstringyesNatural-language description of the change you want to make to the audience/ICP.

No output schema declared.

No examples provided.

publish_blog_article ~77

Push a blog article to connected external platforms (WordPress, Medium, Substack, etc.). Get connection IDs from list_publishing_connections.

NameTypeReqDescription
articleIdstringyesBlog article ID
brandIdstringBrand ID (uses active brand if omitted)
connectionIdsarrayyesConnection IDs to publish to

No output schema declared.

No examples provided.

publish_landing_page ~33

Publish a landing page, making it publicly accessible at its URL.

NameTypeReqDescription
slugstringyesLanding page slug

No output schema declared.

No examples provided.

reddit_generate_pool ~98

Kick off async generation of a subreddit pool for the brand — finds relevant subreddits by crawling Reddit. Typically takes ~1–3 min. Returns { operationId, status }. Poll get_job with the operationId until state=completed, then call reddit_get_pool to see results. Reddit is a repurpose-to-Reddit workflow, NOT a scheduled publishing medium.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)

No output schema declared.

No examples provided.

reddit_get_pool ~144

Returns the brand's pool of relevant subreddits — THIS IS the brand-level subreddit match (each scored). Use it to answer 'which/what/top N subreddits should my brand post in?' — NO content needed; results are sorted most-relevant first; pass `top` for a top-N list. (reddit_suggest is a different, content-specific step.) Reddit is a repurpose-to-Reddit workflow, NOT a scheduled publishing medium.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
topintegerReturn only the top N most-relevant subreddits (results are always sorted most-relevant first)

No output schema declared.

No examples provided.

reddit_global_pool ~50

Return stats on the global subreddit dataset (count of known subreddits available for matching). Informational only — no DB writes.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)

No output schema declared.

No examples provided.

reddit_list_posts ~138

List saved Reddit posts (outputs of reddit_rewrite). Cursor-paginated. Returns { posts: [{ id, platform, content, outputData, sessionId, voiceId, createdAt }], nextCursor }. outputData contains: redditTitle, body, notes, wordCount, angle, length, subreddit, variationIndex. Flow step 4 of 4: pool → suggest → rewrite → LIST_POSTS.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
cursorstringPagination cursor from a previous page
limitintegerPage size (default 20, max 50)

No output schema declared.

No examples provided.

reddit_rewrite ~305

Async. Rewrite a blog article (or raw content) into a Reddit-native post for a specific subreddit. Typically takes ~30–90 sec per variation. This tool polls inline and returns the finished Reddit post once generation completes — you do NOT need to poll separately. If it times out before completing, it returns a postId; call get_post with that postId until operationStatus is COMPLETED. Requires pool to exist. The subreddit must be in the brand's pool. Flow step 3 of 4: pool → suggest → REWRITE → list_posts.

NameTypeReqDescription
anglestringAngle/framing for the post, e.g. 'educational', 'story' (default: 'educational')
brandIdstringBrand ID (defaults to active brand)
lengthstringTarget post length
sourceContentstringRaw content body to rewrite (use this OR sourcePostId)
sourcePostIdstringBlogArticle ID to rewrite (use this OR sourceContent)
sourceTitlestringTitle of the source content (used with sourceContent)
subredditstringyesTarget subreddit name (from reddit_suggest results, e.g. 'entrepreneur')
variationsintegerNumber of variations to generate (default 1, max 3)
voiceIdstringyesVoice profile ID (use list_voices to get IDs; pass 'none' for no voice)

No output schema declared.

No examples provided.

reddit_suggest ~333

Given a brand's content (a blog post by id, or pasted title+text), return up to 8 best-fit subreddits from the brand's pool, each with 2-3 distinct posting angles (angle type + tailored title + framing hook), plus promotion mode, buyer intent, match score, and the key rule to watch. Use an angle's title/hook to then draft a native post via reddit_rewrite. short {subreddit,match_score,promotion_mode,buyer_intent,angle} (angle = first angle only); medium adds reason,rule_to_watch,angles (all angles); full = raw. Synchronous, 0 credits. Requires the brand pool to exist — call reddit_generate_pool first if it doesn't. Flow step 2 of 4: pool → SUGGEST → rewrite → list_posts.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
contentstringContent body (optional; used with title when not passing postId)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "medium". Lists…
postIdstringBlogArticle ID to suggest for (use this OR title+content)
titlestringContent title (required when not passing postId)

No output schema declared.

No examples provided.

regenerate_landing_page ~92

Re-generate a landing page's content using AI. Optionally restrict to specific sections. Returns an operationId — poll with get_job to track progress.

NameTypeReqDescription
instructionsstringExtra guidance for the AI
sectionsarraySpecific section keys to regenerate (omit to regenerate all)
slugstringyesLanding page slug
voiceProfileIdstringVoice profile ID

No output schema declared.

No examples provided.

regenerate_post_visual ~200

Regenerate the visual option set for a post — refreshes stock photo results and re-scores library assets. Returns slim option list with pickArgs by default (medium). Use detail='short' for counts only, 'full' for raw catalog. Includes editInVisualEditor: a direct URL to edit the post in the visual editor (when active brand is set).

NameTypeReqDescription
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "medium". Lists…
loadExternalbooleanAlso reload external stock sources
platformstringLimit regeneration to a specific platform
postIdstringyesPost ID

No output schema declared.

No examples provided.

repurpose_content ~468

Turn a URL, text, blog post, or existing PostKing post into new content for social media or blogs. IMPORTANT: When the source is a URL, pass it directly to this tool via sourceUrl — do NOT fetch or crawl the URL yourself first. PostKing handles all crawling internally. Source types: url | text | blog | social_post. Target types: social (LinkedIn, X, etc.) | blog | text. Supports detail param: short=ids only, medium=key fields (default), full=raw response.

NameTypeReqDescription
anglestringSpecific angle or focus, e.g. 'focus on ROI data'
brandIdstringBrand ID (uses active brand if omitted)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "medium". Lists…
includeLinkbooleanInclude source link in output
sourceBlogIdstringExisting PostKing blog article ID (when sourceType=blog). Get IDs from list_blogs.
sourceContentstringRaw text to repurpose (when sourceType=text)
sourcePostIdstringExisting PostKing post ID (when sourceType=social_post)
sourceTypestringyesWhere the source content comes from
sourceUrlstringURL to repurpose (when sourceType=url)
targetPlatformsarrayPlatforms for social output, e.g. ['x','linkedin']
targetTypestringyesWhat to generate
textLengthstringFor text target: short | medium | long | custom:<words>
themeIdstringContent theme ID to attach
variationsnumber
voiceProfileIdsarrayVoice profile IDs. Single ID applies to all platforms: ['clxvoice1']. Per-platform: ['x:clxvoice1','linkedin:clxvoice2']. Get IDs from list_voices.

No output schema declared.

No examples provided.

reschedule_post ~57

Move a scheduled post to a new time. Pass a future ISO 8601 UTC datetime.

NameTypeReqDescription
postIdstringyesPost ID to reschedule
scheduledAtstringyesNew future ISO 8601 UTC datetime

No output schema declared.

No examples provided.

revoke_api_key ~66

Permanently revoke an API key. Pass confirm: true to proceed — this is irreversible and any clients using this key will stop working immediately.

NameTypeReqDescription
confirmbooleanyesMust be true to confirm revocation
keyIdstringyesAPI key ID from list_api_keys

No output schema declared.

No examples provided.

rewrite_text ~76

Rewrite text using a voice profile or general writing rules.

NameTypeReqDescription
brandIdstringBrand ID (uses active brand if omitted)
platformstringPlatform context: x | linkedin | instagram | threads | facebook
textstringyesText to rewrite
voicestringVoice profile ID to apply

No output schema declared.

No examples provided.

rewrite_with_voice ~73

Rewrite text using a specific voice profile.

NameTypeReqDescription
brandIdstringBrand ID (uses active brand if omitted)
platformstringPlatform context: x | linkedin | instagram | threads | facebook
profileIdstringyesVoice profile ID
textstringyesText to rewrite

No output schema declared.

No examples provided.

run_weekly_schedule_day ~83

Trigger the smart-week content generation engine for a specific date. This immediately queues posts for that day's schedule configuration. Use YYYY-MM-DD format for the date. Returns postsCreated count.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
datestringyesDate to run, e.g. '2026-05-01'

No output schema declared.

No examples provided.

schedule_blog_article ~146

Schedule an existing blog article to auto-publish at a future date/time. scheduledAt must be a future ISO 8601 datetime. When the time arrives, the article publishes to the PostKing blog and auto-pushes to any connected external platforms flagged autoPublish. To publish immediately instead, use update_blog_article with status='published'.

NameTypeReqDescription
articleIdstringyesBlog article ID
brandIdstringBrand ID (uses active brand if omitted)
scheduledAtstringyesISO 8601 datetime in the future, e.g. 2026-07-10T14:30:00Z, when the article should auto-publish

No output schema declared.

No examples provided.

schedule_post ~115

Schedule a draft or approved post for a specific time. Equivalent to approve_post but named to match 'pking posts schedule'. Pass a future ISO 8601 UTC datetime. After scheduling the post status becomes 'scheduled'.

NameTypeReqDescription
postIdstringyesPost ID to schedule
scheduledAtstringyesFuture ISO 8601 UTC datetime, e.g. 2026-06-01T09:00:00Z
timezonestringUser timezone, e.g. 'America/New_York'

No output schema declared.

No examples provided.

search_stock_images ~190

Search stock photo/video libraries for images matching a query. Returns URLs and descriptions. Use import_asset_from_url to add a result to the library. Supports detail param: short=url+thumbnail, medium=adds description+credit, full=raw.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…
platformstringPlatform to optimize image dimensions for, e.g. 'linkedin'
querystringyesSearch query, e.g. 'startup team meeting'

No output schema declared.

No examples provided.

search_web_images ~318

Search Google Images across the whole web for a query — broader than search_stock_images, which only searches licensed stock photo/video libraries. Returns image URLs, the source site, and a link back to the source page. openLicensedOnly is a best-effort source filter, not a legal license guarantee — agents and users should still verify usage rights before publishing any result. Use import_asset_from_url to add a chosen result to the library. Supports detail param: short=url+source, medium=adds sourceUrl+alt+dimensions, full=raw.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…
glstringGoogle country code to bias results, e.g. 'us'
hlstringGoogle language code, e.g. 'en'
maxResultsintegerMaximum number of results to return (1–100)
openLicensedOnlybooleanBest-effort filter to sources that tend to be openly licensed. Not a legal guarantee — still verify usage rights before publishing.
querystringyesSearch query, e.g. 'startup team meeting'

No output schema declared.

No examples provided.

seo_add_seeds ~79

Step 1 of the SEO / GEO flow. Add 3–10 seed keywords that describe what the brand wants to rank for. After this, call seo_generate_keywords to expand them into the full keyword universe.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
seedsarrayyesSeed keywords or topics

No output schema declared.

No examples provided.

seo_approve_briefs ~203

Approves one or more SeoBriefs and AUTO-fires L4 article/comparison generation immediately — do NOT call seo_write_article after this. Typically takes ~3–8 min per article. After approval, poll each returned operationId with get_job until state is `completed` (or `failed`/`partially_failed`/`cancelled` on error). A brief in status `writing` means generation is already in progress — poll the existing operation, do not re-submit. Body: briefIds (array, max 200). Response: { approved, failed: [{briefId, reason}], operationIds, operations: [{briefId, operationId, type}] }.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
briefIdsarrayyesBrief IDs to approve (from seo_list_briefs)
generateHeroImagebooleanAlso generate a hero image per blog brief (extra credits).

No output schema declared.

No examples provided.

seo_approve_cluster ~149

Approve a single cluster. Gates brief generation — only approved clusters get briefs drafted. Position in flow: after seo_generate_clusters + seo_list_clusters, before seo_generate_roadmap / brief review. Typically takes ~2–5 min per cluster. Returns `{ cluster, operationId }` — the operationId is for the async brief-generation job kicked off by approval. Poll `get_job` with the operationId until `state` is `completed` (or `failed`/`partially_failed`/`cancelled` on error).

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
clusterIdstringyesCluster ID from seo_list_clusters

No output schema declared.

No examples provided.

seo_auto_assign_cta ~333

Optional capstone step — runs AFTER blog articles are published. Auto-suggests a published side-page CTA for each blog article in the batch by matching the article's keywords (cluster + tags + title) against the brand's published side pages, then writes the result to BlogArticle.sidePageInfo (header + ctaText + ctaButtonText + ctaHref). Defaults are safe to re-run: skips blogs that already have a CTA (`overwriteExisting=false`) and skips Webflow-synced blogs (`skipWebflowSynced=true`) since CTA edits don't push back to Webflow. Synchronous — returns `{ updated, skipped, errors, total, results: [{blogId, status, sidePageId?, sidePageSlug?}] }` directly; no polling needed. Pass `blogIds: "all"` to process every blog for the brand, or a list of up to 50 blog IDs. Hard cap of 50 blogs per call. For brands with more uncovered blogs, batch your `blogIds` arrays in groups of 50. The matcher uses keywords today; reusing an existing CTA header/ctaText body as a matching signal is a planned enhancement.

NameTypeReqDescription
blogIdsyesBlog article IDs to process, or the literal "all" for every blog in the brand
brandIdstringBrand ID (defaults to active brand)
overwriteExistingbooleanOverwrite blogs that already have a sidePageInfo CTA (default false)
skipWebflowSyncedbooleanSkip blogs with externalProvider=webflow (default true)

No output schema declared.

No examples provided.

seo_bulk_approve_clusters ~159

Step 5b — bulk-approve N clusters in one call. Recommended path when an agent wants to move multiple clusters forward. Approving a cluster fires an async seo_brief_generate Operation per cluster; brief generation only runs on approved clusters. Typically takes ~2–5 min per cluster. Response includes `operations: [{ clusterId, operationId }]` and `operationIds: string[]` — Poll `get_job` with the operationId until `state` is `completed` (or `failed`/`partially_failed`/`cancelled` on error).

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
clusterIdsarrayyesCluster IDs from seo_list_clusters to approve

No output schema declared.

No examples provided.

seo_bulk_reject_clusters ~60

Bulk-reject N clusters in one call. Symmetric to seo_bulk_approve_clusters.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
clusterIdsarrayyesCluster IDs from seo_list_clusters to reject

No output schema declared.

No examples provided.

seo_categorize ~115

Step 3 of the SEO / GEO flow. Tag keywords by search intent and/or user tags. Pass `updates`: an array of `{keywordId, intent?, userTags?}` (intent ∈ informational | commercial | navigational | transactional). Example: {"updates":[{"keywordId":"kw_123","intent":"commercial"}]}. After this, call seo_generate_clusters.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
updatesarrayyesPer-keyword categorization updates

No output schema declared.

No examples provided.

seo_competitor ~193

Compare the brand's keyword coverage against a competitor domain. Returns short detail by default: bucket totals only {overlapping: {total}, brandUnique: {total}, competitorOnly: {total}}. Use detail="medium" for capped keyword lists (up to 50 per bucket) or detail="full" for the raw API response.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
competitorDomainstringyesCompetitor domain, e.g. 'competitor.com'
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…

No output schema declared.

No examples provided.

seo_delete_keyword ~135

Soft-delete a single SeoScoredKeyword (sets deletedAt; the row stays in the DB but is filtered out of all queries). Housekeeping op — not part of the main flow. Pass `confirm: true` to proceed. Use for obvious junk keywords the auto-pipeline missed. Prefer seo_edit_keyword with excludedFromClustering=true when you only want to hold a keyword out of the next clustering pass.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
confirmbooleanyesMust be true to confirm soft-delete
keywordIdstringyesKeyword ID from seo_list_keywords

No output schema declared.

No examples provided.

seo_edit_brief ~304

Edit an SeoBrief before approval. The inner route does NOT accept free-text 'instructions' — refinement is structured. Pass `briefData` (the full replacement JSON for the brief outline — H2s, FAQs, keyword targets, etc.) and/or `status` ('approved' | 'rejected'). Approving via this tool fires L4 article/comparison generation immediately and returns { brief, operationId } — prefer seo_approve_briefs for the canonical approval step. Typical refinement loop: seo_get_brief → mutate briefData locally → seo_edit_brief with the new briefData (status omitted) → seo_approve_briefs.

NameTypeReqDescription
attachedAssetIdstringWhen approving, attach an existing asset to the article.
brandIdstringBrand ID (defaults to active brand)
briefDataFull structured replacement for the brief outline (object). Pulled from seo_get_brief, edited, sent back.
briefIdstringyesBrief ID from seo_list_briefs
generateHeroImagebooleanWhen approving, also generate a hero image (extra credits).
parentSourcestringLanding-brief approval: which parent LP draft to extend from.
statusstringFlip to 'approved' (fires generation) or 'rejected'. Omit to update briefData without changing status.
voiceProfileIdstringWhen approving, write in this voice profile.

No output schema declared.

No examples provided.

seo_edit_keyword ~205

Edit a single SeoScoredKeyword. Housekeeping op — not part of the main flow. At least one of `intent`, `userTags`, `priority`, or `excludedFromClustering` must be supplied. Use to override the auto-detected intent label, attach user tags, manually nudge priority (0..1), or exclude a noisy keyword from clustering. Example: {"keywordId":"kw_123","intent":"commercial","userTags":["enterprise"]}.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
excludedFromClusteringbooleanWhen true, the keyword is held out of the next clustering pass
intentstringOverride the auto-detected search-intent label
keywordIdstringyesKeyword ID from seo_list_keywords
prioritynumberManual priority override in [0,1]
userTagsarrayReplacement array of user tags (overwrites existing tags)

No output schema declared.

No examples provided.

seo_gap ~166

Identify content gaps — topics the brand's competitors cover but the brand doesn't. Returns short detail by default: {id?, topic?, keyword?} labels only per gap. Use detail="medium" for compact gaps (+ searchVolume, difficulty, competitorDomains) or detail="full" for the raw API response.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
detailstringVerbosity of returned item(s): "short" = id + primary label + status (cheap list scan); "medium" = key summary fields + counts (a useful glance); "full" = the complete object. Default "short". Lists…

No output schema declared.

No examples provided.

seo_generate_clusters ~122

Step 4 of the SEO / GEO flow — async cluster-generation step. Groups related keywords into topic clusters that become candidate pillar topics. Typically takes ~1–2 min. Returns `{operationId, status}` — Poll `get_job` with the operationId until `state` is `completed` (or `failed`/`partially_failed`/`cancelled` on error). After completion, call seo_list_clusters to pick a target, then seo_generate_roadmap.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)

No output schema declared.

No examples provided.

seo_generate_keywords ~164

Step 2 of the SEO / GEO flow. Async — expands seed keywords into the full keyword universe. Typically takes ~1–3 min. Uses credits. Returns `{operationId, status}` — Poll `get_job` with the operationId until `state` is `completed` (or `failed`/`partially_failed`/`cancelled` on error). The server picks the expansion size automatically; the only thing the agent can tweak is `autoScore` (defaults to true server-side — set false to skip volume/difficulty scoring). After completion, call seo_categorize.

NameTypeReqDescription
autoScorebooleanWhether to auto-score generated keywords (server default: true)
brandIdstringBrand ID (defaults to active brand)

No output schema declared.

No examples provided.

seo_generate_roadmap ~123

Step 6. Turn one or more clusters into a prioritized content roadmap of blog articles to write. Pass `clusterId` (single) or `clusterIds` (array of cluster IDs from seo_list_clusters) — omit both to roadmap all clusters. After this, call seo_write_article.

NameTypeReqDescription
brandIdstringBrand ID (defaults to active brand)
clusterIdstringSingle cluster ID from seo_list_clusters (convenience for one cluster)
clusterIdsarrayArray of cluster IDs from seo_list_clusters

No output schema declared.

No examples provided.