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.
Available components
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
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- Clear OSI-approved license (MIT).Pass
- Actively maintained (last published 26 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
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
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
claude mcp add bitsandtea-postking-mcp -- npx -y postking-mcp
codex mcp add bitsandtea-postking-mcp -- npx -y postking-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"bitsandtea-postking-mcp": {
"type": "local",
"command": [
"npx",
"-y",
"postking-mcp"
],
"enabled": true
}
}
} openclaw mcp add bitsandtea-postking-mcp --command npx --arg -y --arg postking-mcp
mcp_servers:
bitsandtea-postking-mcp:
command: "npx"
args: ["-y", "postking-mcp"] {
"mcpServers": {
"bitsandtea-postking-mcp": {
"command": "npx",
"args": [
"-y",
"postking-mcp"
]
}
}
} 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.
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.
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.
list_lp_versions ~123
List all saved versions of a landing page. Default detail='short'. Use view_lp_version to see section content.
| Name | Type | Req | Description |
|---|---|---|---|
| detail | string | — | Verbosity 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… |
| slug | string | yes | Landing 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (uses active brand if omitted) |
| detail | string | — | Verbosity 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… |
| kind | string | — | Filter by operation kind (e.g. seo_keyword_generate) |
| limit | integer | — | — |
| state | string | — | Filter 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.
| Name | Type | Req | Description |
|---|---|---|---|
| detail | string | — | Verbosity 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… |
| postId | string | yes | Post 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (uses active brand if omitted) |
| detail | string | — | Verbosity 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… |
| limit | number | — | — |
| platform | string | — | — |
| status | string | — | — |
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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (uses active brand if omitted) |
| detail | string | — | Verbosity 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.).
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (uses active brand if omitted) |
| publicationId | string | yes | Blog 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.
| Name | Type | Req | Description |
|---|---|---|---|
| detail | string | — | Verbosity 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… |
| slug | string | yes | Parent 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (uses active brand if omitted) |
| detail | string | — | Verbosity 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.
| Name | Type | Req | Description |
|---|---|---|---|
| detail | string | — | Verbosity 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.
| Name | Type | Req | Description |
|---|---|---|---|
| name | string | — | Brand name (inferred from site if omitted) |
| websiteUrl | string | yes | The 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).
| Name | Type | Req | Description |
|---|---|---|---|
| assetId | string | — | Library asset ID from list_assets |
| kind | string | — | Visual 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… |
| platform | string | yes | Target platform, e.g. 'linkedin' |
| postId | string | yes | Post ID |
| slot | string | — | Internal template slot key (advanced) |
| style | string | — | Template style name from generate_post_visual_options |
| variant | integer | — | Template 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| prompt | string | yes | Natural-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.
| Name | Type | Req | Description |
|---|---|---|---|
| articleId | string | yes | Blog article ID |
| brandId | string | — | Brand ID (uses active brand if omitted) |
| connectionIds | array | yes | Connection 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.
| Name | Type | Req | Description |
|---|---|---|---|
| slug | string | yes | Landing 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| top | integer | — | Return 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| cursor | string | — | Pagination cursor from a previous page |
| limit | integer | — | Page 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.
| Name | Type | Req | Description |
|---|---|---|---|
| angle | string | — | Angle/framing for the post, e.g. 'educational', 'story' (default: 'educational') |
| brandId | string | — | Brand ID (defaults to active brand) |
| length | string | — | Target post length |
| sourceContent | string | — | Raw content body to rewrite (use this OR sourcePostId) |
| sourcePostId | string | — | BlogArticle ID to rewrite (use this OR sourceContent) |
| sourceTitle | string | — | Title of the source content (used with sourceContent) |
| subreddit | string | yes | Target subreddit name (from reddit_suggest results, e.g. 'entrepreneur') |
| variations | integer | — | Number of variations to generate (default 1, max 3) |
| voiceId | string | yes | Voice 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| content | string | — | Content body (optional; used with title when not passing postId) |
| detail | string | — | Verbosity 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… |
| postId | string | — | BlogArticle ID to suggest for (use this OR title+content) |
| title | string | — | Content 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.
| Name | Type | Req | Description |
|---|---|---|---|
| instructions | string | — | Extra guidance for the AI |
| sections | array | — | Specific section keys to regenerate (omit to regenerate all) |
| slug | string | yes | Landing page slug |
| voiceProfileId | string | — | Voice 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).
| Name | Type | Req | Description |
|---|---|---|---|
| detail | string | — | Verbosity 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… |
| loadExternal | boolean | — | Also reload external stock sources |
| platform | string | — | Limit regeneration to a specific platform |
| postId | string | yes | Post 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.
| Name | Type | Req | Description |
|---|---|---|---|
| angle | string | — | Specific angle or focus, e.g. 'focus on ROI data' |
| brandId | string | — | Brand ID (uses active brand if omitted) |
| detail | string | — | Verbosity 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… |
| includeLink | boolean | — | Include source link in output |
| sourceBlogId | string | — | Existing PostKing blog article ID (when sourceType=blog). Get IDs from list_blogs. |
| sourceContent | string | — | Raw text to repurpose (when sourceType=text) |
| sourcePostId | string | — | Existing PostKing post ID (when sourceType=social_post) |
| sourceType | string | yes | Where the source content comes from |
| sourceUrl | string | — | URL to repurpose (when sourceType=url) |
| targetPlatforms | array | — | Platforms for social output, e.g. ['x','linkedin'] |
| targetType | string | yes | What to generate |
| textLength | string | — | For text target: short | medium | long | custom:<words> |
| themeId | string | — | Content theme ID to attach |
| variations | number | — | — |
| voiceProfileIds | array | — | Voice 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.
| Name | Type | Req | Description |
|---|---|---|---|
| postId | string | yes | Post ID to reschedule |
| scheduledAt | string | yes | New 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.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | yes | Must be true to confirm revocation |
| keyId | string | yes | API 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (uses active brand if omitted) |
| platform | string | — | Platform context: x | linkedin | instagram | threads | facebook |
| text | string | yes | Text to rewrite |
| voice | string | — | Voice profile ID to apply |
No output schema declared.
No examples provided.
rewrite_with_voice ~73
Rewrite text using a specific voice profile.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (uses active brand if omitted) |
| platform | string | — | Platform context: x | linkedin | instagram | threads | facebook |
| profileId | string | yes | Voice profile ID |
| text | string | yes | Text 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| date | string | yes | Date 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'.
| Name | Type | Req | Description |
|---|---|---|---|
| articleId | string | yes | Blog article ID |
| brandId | string | — | Brand ID (uses active brand if omitted) |
| scheduledAt | string | yes | ISO 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'.
| Name | Type | Req | Description |
|---|---|---|---|
| postId | string | yes | Post ID to schedule |
| scheduledAt | string | yes | Future ISO 8601 UTC datetime, e.g. 2026-06-01T09:00:00Z |
| timezone | string | — | User 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| detail | string | — | Verbosity 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… |
| platform | string | — | Platform to optimize image dimensions for, e.g. 'linkedin' |
| query | string | yes | Search 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| detail | string | — | Verbosity 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… |
| gl | string | — | Google country code to bias results, e.g. 'us' |
| hl | string | — | Google language code, e.g. 'en' |
| maxResults | integer | — | Maximum number of results to return (1–100) |
| openLicensedOnly | boolean | — | Best-effort filter to sources that tend to be openly licensed. Not a legal guarantee — still verify usage rights before publishing. |
| query | string | yes | Search 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| seeds | array | yes | Seed 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}] }.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| briefIds | array | yes | Brief IDs to approve (from seo_list_briefs) |
| generateHeroImage | boolean | — | Also 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).
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| clusterId | string | yes | Cluster 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.
| Name | Type | Req | Description |
|---|---|---|---|
| blogIds | — | yes | Blog article IDs to process, or the literal "all" for every blog in the brand |
| brandId | string | — | Brand ID (defaults to active brand) |
| overwriteExisting | boolean | — | Overwrite blogs that already have a sidePageInfo CTA (default false) |
| skipWebflowSynced | boolean | — | Skip 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).
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| clusterIds | array | yes | Cluster 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| clusterIds | array | yes | Cluster 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| updates | array | yes | Per-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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| competitorDomain | string | yes | Competitor domain, e.g. 'competitor.com' |
| detail | string | — | Verbosity 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| confirm | boolean | yes | Must be true to confirm soft-delete |
| keywordId | string | yes | Keyword 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.
| Name | Type | Req | Description |
|---|---|---|---|
| attachedAssetId | string | — | When approving, attach an existing asset to the article. |
| brandId | string | — | Brand ID (defaults to active brand) |
| briefData | — | — | Full structured replacement for the brief outline (object). Pulled from seo_get_brief, edited, sent back. |
| briefId | string | yes | Brief ID from seo_list_briefs |
| generateHeroImage | boolean | — | When approving, also generate a hero image (extra credits). |
| parentSource | string | — | Landing-brief approval: which parent LP draft to extend from. |
| status | string | — | Flip to 'approved' (fires generation) or 'rejected'. Omit to update briefData without changing status. |
| voiceProfileId | string | — | When 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"]}.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| excludedFromClustering | boolean | — | When true, the keyword is held out of the next clustering pass |
| intent | string | — | Override the auto-detected search-intent label |
| keywordId | string | yes | Keyword ID from seo_list_keywords |
| priority | number | — | Manual priority override in [0,1] |
| userTags | array | — | Replacement 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| detail | string | — | Verbosity 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand 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.
| Name | Type | Req | Description |
|---|---|---|---|
| autoScore | boolean | — | Whether to auto-score generated keywords (server default: true) |
| brandId | string | — | Brand 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.
| Name | Type | Req | Description |
|---|---|---|---|
| brandId | string | — | Brand ID (defaults to active brand) |
| clusterId | string | — | Single cluster ID from seo_list_clusters (convenience for one cluster) |
| clusterIds | array | — | Array of cluster IDs from seo_list_clusters |
No output schema declared.
No examples provided.