io.github.bitsandtea/postking-mcp
NPM · POSTKING-MCP · 2 COMPONENTS · SCANNED SEP 30
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 → Why this is hard to score →
Supply Chain Security98
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- No install/post-install scripts declared.Pass
- 31 of 94 dependencies flagged as unhealthy. 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 84 days ago).Pass
- Disclosure check failed: no security disclosure policy was found in the source repository. See how to fix → Fail
Schema Quality & AI Usability83
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (excellent).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 Management100
- No destabilizing schema changes in the last 30 days.Pass
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
Tool Safety75
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- 0 of 25 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "delete_theme" implies "delete" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
- An AI judge read all 221 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the io.github.bitsandtea/postking-mcp server?
io.github.bitsandtea/postking-mcp runs locally as an npm package, launched with npx -y postking-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · postking-mcp
claude mcp add bitsandtea-postking-mcp -- npx -y postking-mcp
{
"mcpServers": {
"bitsandtea-postking-mcp": {
"command": "npx",
"args": [
"-y",
"postking-mcp"
]
}
}
} {
"servers": {
"bitsandtea-postking-mcp": {
"command": "npx",
"args": [
"-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": {
"Transport": "stdio",
"Command": "npx",
"Arguments": [
"-y",
"postking-mcp"
]
}
}
} assistant mcp add bitsandtea-postking-mcp -t stdio -c npx -a -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.
- 30 Sept 26 +1
- Stability: 0.97 → pass security
- 28 Sept 26 +1
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 26 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.
- 25 Sept 26 +15
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 23 Sept 26 −3
- Stability: pass → 0.77 functional
- 22 Sept 26 +1
- Stability: 0.97 → pass security
- 20 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.
- 18 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.
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 30 Sept 2026 · Analysed npm/postking-mcp@1.1.7
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | npm |
Background: How many MCP packages publish verified provenance →
Dependencies 94 packages
| Packages resolved | 94 |
|---|---|
| Stale | 31 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
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. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
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.
What is the io.github.bitsandtea/postking-mcp server?
io.github.bitsandtea/postking-mcp is listed in the public MCP registry as io.github.bitsandtea/postking-mcp. PostKing MCP server for managing brands, generating posts, scheduling content, and publishing blogs. This page covers its npm package (postking-mcp).
Is the io.github.bitsandtea/postking-mcp server safe to use?
io.github.bitsandtea/postking-mcp scores 84 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 30 September 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the io.github.bitsandtea/postking-mcp server expose?
io.github.bitsandtea/postking-mcp exposes 220 tools: login_start, login_complete, logout, whoami, list_brands, and 215 more. Their descriptions and schemas cost roughly 31,224 tokens of context every time the server is loaded.
Is the io.github.bitsandtea/postking-mcp server still maintained?
io.github.bitsandtea/postking-mcp is still listed as active in the MCP registry. We last reached this channel on 30 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the io.github.bitsandtea/postking-mcp server under?
io.github.bitsandtea/postking-mcp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.