Skip to main content
Glama

Save Post

save_post

Creates a new draft (omit postId; channel required) or edits an existing post: text, channel fields, media, angle, pillar, buyer questions, proposed time. Never submits or publishes. Returns a save receipt: scheduledAt, assetIds, channel, counted body length, buyerQuestions, idea, updatedAt, and checks (Mark's six content checks on the saved content, including placeholder; a fail is not a refused save, but submit_post refuses a draft while it fails). On a draft or changes-requested post, rev does not change; use updatedAt to confirm the save. A post in review, approved or scheduled needs rev (from get_post): the edit saves as the next rev and the post goes back to in review, so a person approves it again; a stale rev is refused, and so is a phrase this workspace blocks or a placeholder like [needs source]. On those posts ideaId or guideVersion alone is refused, since it would drop the approval without changing what publishes. Posts in any other status are locked. A website post that is not archived (in review, approved, scheduled, published, failed or missed) also takes postId with buyerQuestionIds alone: that replaces the buyer questions it answers and nothing else, so its status, rev, content and approval stay as they are. Asset ids that are not in this workspace are listed as dropped, never attached silently. Likewise droppedMetaKeys lists the top-level meta keys the channel does not take, which the save ignored; the save still succeeds. A LinkedIn post can carry one PDF asset (kind document) and no other media, up to 100 MB; meta.documentTitle is the title LinkedIn shows above it, else the file name. A PDF with other media, over 100 MB, or on another channel is refused with the message submit_post gives. An angle sets the post's pillar and persona to the angle's; a pillarId that contradicts the angle is refused. Website posts (blog, faq, competitor_page, landing_page) take a pillar, never an angle, plus the buyer questions the page answers (buyerQuestionIds, from get_ai_visibility). An email takes a plain-text body and meta { subject, preheader? } (preheader is the inbox preview text); Mark doesn't send email yet, so an approved email stays approved for you to send from your email tool. A LinkedIn Article (linkedin_article) takes a Markdown body and meta { title, cover? }; it needs no connected account, and once approved it waits for a person to publish it on LinkedIn and record the URL with record_post_published. ideaId links the post to an idea from list_ideas (null unlinks); linking never changes the post's pillar, persona or angle. A new draft with ideaId takes what the call leaves unset from the idea: its pillar and angle (a website post takes the pillar and persona, never the angle), its buyer question on a website post while that question is active, and a body that starts with the idea's title and brief. Call get_channel_rules first. To send it for review, call submit_post after saving. Related: get_post, submit_post, add_asset, list_ideas.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
revNoThe post's current rev from get_post. Required to edit a post in review, approved or scheduled; ignored on drafts.
bodyNoPost body / caption.
metaNoChannel-specific fields from get_channel_rules. Instagram and LinkedIn: altText is the post-wide alt text and altTexts is one alt text per image in media order; a blank entry uses altText, and videos and PDFs take none. LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId, collection }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; collection is the media collection search_cms_media named (left out, the default from get_website_cms; one Mark cannot read is refused). Mark fills in the type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. mediaOrder sets the order of the media on post 1 across assets and CMS images: a list of keys, an asset id as is or cms:~<collection>:<mediaId> for a CMS image (get_post shows the collection of each; an image saved before names a channel instead, cms:<channel>:<mediaId>; cms::<mediaId> for an image sent without either). An unknown or repeated key is dropped and media it leaves out goes last; without it, assets go first, then CMS images. altTexts follow this media order. meta without mediaOrder keeps the saved order; [] resets it. On Instagram, LinkedIn and Pinterest, a newly attached CMS image with blank alt text takes the CMS alt (its altTexts entry on a post with several media, else altText; on Pinterest only when it is the only image on the pin). Edit or clear it like any alt text. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], ["id"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: "asset", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: "cms", mediaId, collection, alt? } with an image already in the connected CMS from search_cms_media called with the same channel (collection left out: the default for that channel; a cover comes only from the collection the cover field accepts, else where new media goes, and any other is refused; Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media (any readable collection): on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which).
ideaIdNoIdea id from list_ideas, or null to unlink. Archived ideas can't be newly linked. On a new draft, unset pillar, angle, buyer questions and body come from the idea.
postIdNoExisting post to edit. Omit to create a new draft.
angleIdNoAngle id, or null to clear. Social posts only; refused on website posts. Sets the post's pillar and persona to the angle's.
channelNoRequired to create a draft. When editing, omit it or pass the post's current channel — the channel cannot be changed here.
assetIdsNoAsset ids from search_assets / add_asset, in order. Instagram takes at most 10; more is refused with an assetIds error. An X thread lists every asset in the thread here; meta.threadMedia says which reply each goes on. Website posts take no attachments: set meta.cover instead (assetIds may be omitted or hold only the cover id); other images go in the body as Markdown.
pillarIdNoPillar id, or null to clear. With an angle, omit it or pass the angle's own pillar; any other value, null included, is refused.
scheduledAtNoProposed publish time as a UTC ISO string, or null.
guideVersionNoguideVersion from get_drafting_guide for this channel, after checking the draft against that guide.
buyerQuestionIdsNoWebsite posts only: the buyer question ids this page answers, from get_ai_visibility. Replaces the set; null or [] clears it; omit to keep it. Active questions only, except ones already linked. Refused on social posts. Sent alone with postId, it also changes a submitted or live website post, without review; refused once archived.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
revYes
ideaYesThe idea the post is linked to after this save.
appUrlYes
assetsYes
checksYesMark's content checks on the saved content: exclusion, char_limit, required_meta, ai_fluff, unsourced_number, placeholder, and on a competitor_page also table and open_placeholder. On a draft, a fail stops submit_post; warn never does.
guidedYesWhether the post was saved against the workspace's current drafting guide.
postIdYes
statusYes
channelYes
assetIdsYes
updatedAtYes
bodyLengthYes
contentHashYes
scheduledAtYes
guideVersionYesThe drafting guide version recorded on the post, or null.
buyerQuestionsYesThe buyer questions the post answers after this save.
characterLimitYes
droppedAssetIdsYes
droppedMetaKeysYesTop-level meta keys this channel does not take, so the save ignored them. Empty when none.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in media order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. mediaOrder sets the order of the media on post 1 across assets and CMS images: a list of keys, an asset id as is or cms:<channel>:<mediaId> for a CMS image (get_post shows the channel of each; cms::<mediaId> for an image sent without one). An unknown or repeated key is dropped and media it leaves out goes last; without it, assets go first, then CMS images. altTexts follow this media order. meta without mediaOrder keeps the saved order; [] resets it. On Instagram and Pinterest, a newly attached CMS image with blank alt text takes the CMS alt (its altTexts entry on a carousel, else altText; on Pinterest only when it is the only image on the pin). Edit or clear it like any alt text. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media called with the same channel: on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which)."New value: +"Channel-specific fields from get_channel_rules. Instagram and LinkedIn: altText is the post-wide alt text and altTexts is one alt text per image in media order; a blank entry uses altText, and videos and PDFs take none. LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId, collection }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; collection is the media collection search_cms_media named (left out, the default from get_website_cms; one Mark cannot read is refused). Mark fills in the type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. mediaOrder sets the order of the media on post 1 across assets and CMS images: a list of keys, an asset id as is or cms:~<collection>:<mediaId> for a CMS image (get_post shows the collection of each; an image saved before names a channel instead, cms:<channel>:<mediaId>; cms::<mediaId> for an image sent without either). An unknown or repeated key is dropped and media it leaves out goes last; without it, assets go first, then CMS images. altTexts follow this media order. meta without mediaOrder keeps the saved order; [] resets it. On Instagram, LinkedIn and Pinterest, a newly attached CMS image with blank alt text takes the CMS alt (its altTexts entry on a post with several media, else altText; on Pinterest only when it is the only image on the pin). Edit or clear it like any alt text. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, collection, alt? } with an image already in the connected CMS from search_cms_media called with the same channel (collection left out: the default for that channel; a cover comes only from the collection the cover field accepts, else where new media goes, and any other is refused; Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media (any readable collection): on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which)."
    • addedOutput schema / properties / droppedMetaKeys
      Added value: +{
      +  "description": "Top-level meta keys this channel does not take, so the save ignored them. Empty when none.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "appUrl",
      -  "assetIds",
      -  "assets",
      -  "bodyLength",
      -  "buyerQuestions",
      -  "channel",
      -  "characterLimit",
      -  "checks",
      -  "contentHash",
      -  "droppedAssetIds",
      -  "idea",
      -  "guided",
      -  "guideVersion",
      -  "postId",
      -  "rev",
      -  "scheduledAt",
      -  "status",
      -  "updatedAt"
      -]New value: +[
      +  "appUrl",
      +  "assetIds",
      +  "assets",
      +  "bodyLength",
      +  "buyerQuestions",
      +  "channel",
      +  "characterLimit",
      +  "checks",
      +  "contentHash",
      +  "droppedAssetIds",
      +  "droppedMetaKeys",
      +  "idea",
      +  "guided",
      +  "guideVersion",
      +  "postId",
      +  "rev",
      +  "scheduledAt",
      +  "status",
      +  "updatedAt"
      +]
  2. Changed1 schema field changed
    • changedInput schema / properties / channel / enum
      Previous value: -[
      -  "instagram",
      -  "facebook",
      -  "youtube",
      -  "pinterest",
      -  "tiktok",
      -  "x",
      -  "linkedin",
      -  "blog",
      -  "faq",
      -  "competitor_page",
      -  "landing_page",
      -  "email"
      -]New value: +[
      +  "instagram",
      +  "facebook",
      +  "youtube",
      +  "pinterest",
      +  "tiktok",
      +  "x",
      +  "linkedin",
      +  "linkedin_article",
      +  "blog",
      +  "faq",
      +  "competitor_page",
      +  "landing_page",
      +  "email"
      +]
  3. Changed2 schema fields changed
    • changedOutput schema / properties / checks / description
      Previous value: -"Mark's content checks on the saved content: exclusion, char_limit, required_meta, ai_fluff, unsourced_number, placeholder. On a draft, a fail stops submit_post; warn never does."New value: +"Mark's content checks on the saved content: exclusion, char_limit, required_meta, ai_fluff, unsourced_number, placeholder, and on a competitor_page also table and open_placeholder. On a draft, a fail stops submit_post; warn never does."
    • changedOutput schema / properties / checks / items / properties / checkId / enum
      Previous value: -[
      -  "exclusion",
      -  "char_limit",
      -  "required_meta",
      -  "ai_fluff",
      -  "unsourced_number",
      -  "placeholder"
      -]New value: +[
      +  "exclusion",
      +  "char_limit",
      +  "required_meta",
      +  "ai_fluff",
      +  "unsourced_number",
      +  "placeholder",
      +  "table",
      +  "open_placeholder"
      +]
  4. Changed1 schema field changed
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. On Instagram and Pinterest, a newly attached CMS image with blank alt text takes the CMS alt (its altTexts entry on a carousel, else altText; on Pinterest only when it is the only image on the pin). Edit or clear it like any alt text. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media called with the same channel: on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which)."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in media order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. mediaOrder sets the order of the media on post 1 across assets and CMS images: a list of keys, an asset id as is or cms:<channel>:<mediaId> for a CMS image (get_post shows the channel of each; cms::<mediaId> for an image sent without one). An unknown or repeated key is dropped and media it leaves out goes last; without it, assets go first, then CMS images. altTexts follow this media order. meta without mediaOrder keeps the saved order; [] resets it. On Instagram and Pinterest, a newly attached CMS image with blank alt text takes the CMS alt (its altTexts entry on a carousel, else altText; on Pinterest only when it is the only image on the pin). Edit or clear it like any alt text. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media called with the same channel: on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which)."
  5. Changed1 schema field changed
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media called with the same channel: on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which)."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. On Instagram and Pinterest, a newly attached CMS image with blank alt text takes the CMS alt (its altTexts entry on a carousel, else altText; on Pinterest only when it is the only image on the pin). Edit or clear it like any alt text. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media called with the same channel: on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which)."
  6. Changed1 schema field changed
    • changedInput schema / properties / channel / enum
      Previous value: -[
      -  "instagram",
      -  "facebook",
      -  "youtube",
      -  "pinterest",
      -  "tiktok",
      -  "x",
      -  "linkedin",
      -  "blog",
      -  "faq",
      -  "competitor_page"
      -]New value: +[
      +  "instagram",
      +  "facebook",
      +  "youtube",
      +  "pinterest",
      +  "tiktok",
      +  "x",
      +  "linkedin",
      +  "blog",
      +  "faq",
      +  "competitor_page",
      +  "landing_page",
      +  "email"
      +]
  7. Changed1 schema field changed
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover. An image already in the CMS goes in the body as ![alt](url) on its own line, with url from search_cms_media called with the same channel: on a rich-text mapping it publishes by reference with no upload and shows the alt text the CMS has (get_channel_rules says which)."
  8. Changed3 schema fields changed
    • changedInput schema / properties / assetIds / description
      Previous value: -"Asset ids from search_assets / add_asset, in order. Instagram takes at most 10; more is refused with an assetIds error. Website posts take no attachments: set meta.cover instead (assetIds may be omitted or hold only the cover id); other images go in the body as Markdown."New value: +"Asset ids from search_assets / add_asset, in order. Instagram takes at most 10; more is refused with an assetIds error. An X thread lists every asset in the thread here; meta.threadMedia says which reply each goes on. Website posts take no attachments: set meta.cover instead (assetIds may be omitted or hold only the cover id); other images go in the body as Markdown."
    • changedInput schema / properties / buyerQuestionIds / description
      Previous value: -"Website posts only: the buyer question ids this page answers, from get_ai_visibility. Replaces the set; null or [] clears it; omit to keep it. Active questions only, except ones already linked. Refused on social posts."New value: +"Website posts only: the buyer question ids this page answers, from get_ai_visibility. Replaces the set; null or [] clears it; omit to keep it. Active questions only, except ones already linked. Refused on social posts. Sent alone with postId, it also changes a submitted or live website post, without review; refused once archived."
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Social posts (not YouTube): cmsImages: [{ mediaId }] attaches images already in the connected CMS (search_cms_media), after the assets on post 1; Mark fills in the channel, type and size of each, takes JPEG, PNG, WebP or GIF, and copies them to the platform at scheduling. They count toward media limits like assets. X: thread is the replies after the body, in order; threadMedia puts media on a reply: one list of asset ids per thread entry, in the same order ([[], [\"id\"]] puts id on post 3). Every threadMedia id must also be in assetIds and on one post only; post 1 gets the assetIds no reply lists. meta replaces the saved meta: when thread keeps its number of replies and threadMedia is left out, the saved threadMedia carries over; when the number changes, send threadMedia too. Each X thread post takes up to 4 images, or 1 video, or 1 GIF. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover."
  9. Changed2 schema fields changed
    • changedOutput schema / properties / checks / description
      Previous value: -"Mark's content checks on the saved content: exclusion, char_limit, required_meta, ai_fluff, unsourced_number. On a draft, a fail stops submit_post; warn never does."New value: +"Mark's content checks on the saved content: exclusion, char_limit, required_meta, ai_fluff, unsourced_number, placeholder. On a draft, a fail stops submit_post; warn never does."
    • changedOutput schema / properties / checks / items / properties / checkId / enum
      Previous value: -[
      -  "exclusion",
      -  "char_limit",
      -  "required_meta",
      -  "ai_fluff",
      -  "unsourced_number"
      -]New value: +[
      +  "exclusion",
      +  "char_limit",
      +  "required_meta",
      +  "ai_fluff",
      +  "unsourced_number",
      +  "placeholder"
      +]
  10. Changed1 schema field changed
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). LinkedIn: documentTitle is the line LinkedIn shows above an attached PDF; blank uses the file name. Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover."
  11. Changed1 schema field changed
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset; alt is required before submit when the CMS takes a cover. Omit cover for no cover."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset, or cover: { source: \"cms\", mediaId, alt? } with an image already in the connected CMS from search_cms_media (Mark fills its type and size, alt defaults to the CMS alt, and an edited alt is written back to that CMS image on approve). alt is required before submit when the CMS takes a cover. Omit cover for no cover."
  12. Changed2 schema fields changed
    • changedInput schema / properties / assetIds / description
      Previous value: -"Asset ids from search_assets / add_asset, in order. Instagram takes at most 10; more is refused with an assetIds error."New value: +"Asset ids from search_assets / add_asset, in order. Instagram takes at most 10; more is refused with an assetIds error. Website posts take no attachments: set meta.cover instead (assetIds may be omitted or hold only the cover id); other images go in the body as Markdown."
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none)."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none). Website posts (blog, faq, landing_page, competitor_page): the cover is cover: { source: \"asset\", assetId, alt } with an image id from search_assets / add_asset; alt is required before submit when the CMS takes a cover. Omit cover for no cover."
  13. Changed1 schema field changed
    • addedInput schema / properties / rev
      Added value: +{
      +  "description": "The post's current rev from get_post. Required to edit a post in review, approved or scheduled; ignored on drafts.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
  14. Changed5 schema fields changed
    • addedInput schema / properties / guideVersion
      Added value: +{
      +  "description": "guideVersion from get_drafting_guide for this channel, after checking the draft against that guide.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / checks
      Added value: +{
      +  "description": "Mark's content checks on the saved content: exclusion, char_limit, required_meta, ai_fluff, unsourced_number. On a draft, a fail stops submit_post; warn never does.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "checkId": {
      +        "enum": [
      +          "exclusion",
      +          "char_limit",
      +          "required_meta",
      +          "ai_fluff",
      +          "unsourced_number"
      +        ],
      +        "type": "string"
      +      },
      +      "matches": {
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "end": {
      +              "type": "number"
      +            },
      +            "exclusionId": {
      +              "type": "string"
      +            },
      +            "field": {
      +              "type": "string"
      +            },
      +            "reason": {
      +              "type": "string"
      +            },
      +            "severity": {
      +              "enum": [
      +                "block",
      +                "warn"
      +              ],
      +              "type": "string"
      +            },
      +            "start": {
      +              "type": "number"
      +            },
      +            "text": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "field",
      +            "start",
      +            "end",
      +            "text"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "status": {
      +        "enum": [
      +          "pass",
      +          "warn",
      +          "fail"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "checkId",
      +      "status",
      +      "matches"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / guideVersion
      Added value: +{
      +  "description": "The drafting guide version recorded on the post, or null.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / guided
      Added value: +{
      +  "description": "Whether the post was saved against the workspace's current drafting guide.",
      +  "type": "boolean"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "appUrl",
      -  "assetIds",
      -  "assets",
      -  "bodyLength",
      -  "buyerQuestions",
      -  "channel",
      -  "characterLimit",
      -  "contentHash",
      -  "droppedAssetIds",
      -  "idea",
      -  "postId",
      -  "rev",
      -  "scheduledAt",
      -  "status",
      -  "updatedAt"
      -]New value: +[
      +  "appUrl",
      +  "assetIds",
      +  "assets",
      +  "bodyLength",
      +  "buyerQuestions",
      +  "channel",
      +  "characterLimit",
      +  "checks",
      +  "contentHash",
      +  "droppedAssetIds",
      +  "idea",
      +  "guided",
      +  "guideVersion",
      +  "postId",
      +  "rev",
      +  "scheduledAt",
      +  "status",
      +  "updatedAt"
      +]
  15. Changed3 schema fields changed
    • addedInput schema / properties / ideaId
      Added value: +{
      +  "anyOf": [
      +    {
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Idea id from list_ideas, or null to unlink. Archived ideas can't be newly linked. On a new draft, unset pillar, angle, buyer questions and body come from the idea."
      +}
    • addedOutput schema / properties / idea
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "archived": {
      +          "type": "boolean"
      +        },
      +        "id": {
      +          "type": "string"
      +        },
      +        "title": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "archived",
      +        "id",
      +        "title"
      +      ],
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "The idea the post is linked to after this save."
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "appUrl",
      -  "assetIds",
      -  "assets",
      -  "bodyLength",
      -  "buyerQuestions",
      -  "channel",
      -  "characterLimit",
      -  "contentHash",
      -  "droppedAssetIds",
      -  "postId",
      -  "rev",
      -  "scheduledAt",
      -  "status",
      -  "updatedAt"
      -]New value: +[
      +  "appUrl",
      +  "assetIds",
      +  "assets",
      +  "bodyLength",
      +  "buyerQuestions",
      +  "channel",
      +  "characterLimit",
      +  "contentHash",
      +  "droppedAssetIds",
      +  "idea",
      +  "postId",
      +  "rev",
      +  "scheduledAt",
      +  "status",
      +  "updatedAt"
      +]
  16. Changed3 schema fields changed
    • addedInput schema / properties / buyerQuestionIds
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Website posts only: the buyer question ids this page answers, from get_ai_visibility. Replaces the set; null or [] clears it; omit to keep it. Active questions only, except ones already linked. Refused on social posts."
      +}
    • addedOutput schema / properties / buyerQuestions
      Added value: +{
      +  "description": "The buyer questions the post answers after this save.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": "string"
      +      },
      +      "question": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id",
      +      "question"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "appUrl",
      -  "assetIds",
      -  "assets",
      -  "bodyLength",
      -  "channel",
      -  "characterLimit",
      -  "contentHash",
      -  "droppedAssetIds",
      -  "postId",
      -  "rev",
      -  "scheduledAt",
      -  "status",
      -  "updatedAt"
      -]New value: +[
      +  "appUrl",
      +  "assetIds",
      +  "assets",
      +  "bodyLength",
      +  "buyerQuestions",
      +  "channel",
      +  "characterLimit",
      +  "contentHash",
      +  "droppedAssetIds",
      +  "postId",
      +  "rev",
      +  "scheduledAt",
      +  "status",
      +  "updatedAt"
      +]
  17. Changed2 schema fields changed
    • changedInput schema / properties / angleId / description
      Previous value: -"Angle id, or null to clear."New value: +"Angle id, or null to clear. Social posts only; refused on website posts. Sets the post's pillar and persona to the angle's."
    • changedInput schema / properties / pillarId / description
      Previous value: -"Pillar id, or null to clear."New value: +"Pillar id, or null to clear. With an angle, omit it or pass the angle's own pillar; any other value, null included, is refused."
  18. Changed2 schema fields changed
    • changedInput schema / properties / assetIds / description
      Previous value: -"Asset ids from search_assets / add_asset, in order."New value: +"Asset ids from search_assets / add_asset, in order. Instagram takes at most 10; more is refused with an assetIds error."
    • changedInput schema / properties / meta / description
      Previous value: -"Channel-specific fields from get_channel_rules."New value: +"Channel-specific fields from get_channel_rules. Instagram: altTexts is one alt text per slide in assetIds order (blank entries and videos use altText or none)."
  19. Changed10 schema fields changed
    • addedOutput schema / properties / assetIds
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / assets
      Added value: +{
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "id": {
      +        "type": "string"
      +      },
      +      "kind": {
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id",
      +      "kind",
      +      "name"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / bodyLength
      Added value: +{
      +  "type": "number"
      +}
    • addedOutput schema / properties / channel
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / characterLimit
      Added value: +{
      +  "type": [
      +    "number",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / contentHash
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / droppedAssetIds
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / scheduledAt
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / updatedAt
      Added value: +{
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "appUrl",
      -  "postId",
      -  "rev",
      -  "status"
      -]New value: +[
      +  "appUrl",
      +  "assetIds",
      +  "assets",
      +  "bodyLength",
      +  "channel",
      +  "characterLimit",
      +  "contentHash",
      +  "droppedAssetIds",
      +  "postId",
      +  "rev",
      +  "scheduledAt",
      +  "status",
      +  "updatedAt"
      +]
  20. First observed

TDQS

Score is being calculated.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources