addedInput schema / properties / embed / description
Added value: +"Optional media embed: images OR an external link card OR a video (at most one)."
addedInput schema / properties / embed / properties / external / description
Added value: +"An external link card to attach. Mutually exclusive with `images`, `video`, and `quote`."
addedInput schema / properties / embed / properties / external / properties / description / description
Added value: +"Description shown on the external link card (max 1000 characters)."
addedInput schema / properties / embed / properties / external / properties / thumb
Added value: +{
+ "additionalProperties": false,
+ "description": "Optional thumbnail for the link card as a pre-uploaded blob descriptor: pass the `preview.thumb.blob` object from generate_link_preview (or the `image.blob` from upload_image) verbatim. Omit for a card without a thumbnail.",
+ "properties": {
+ "mimeType": {
+ "description": "MIME type of the uploaded blob (e.g. \"image/jpeg\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ "ref": {
+ "anyOf": [
+ {
+ "description": "CID of the uploaded blob as a flat string (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "additionalProperties": false,
+ "description": "Lexicon blob-ref object wrapping the CID as { \"$link\": \"<cid>\" }.",
+ "properties": {
+ "$link": {
+ "description": "CID of the uploaded blob (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "$link"
+ ],
+ "type": "object"
+ }
+ ],
+ "description": "CID reference of the uploaded blob: either the flat string returned by upload_image, or the lexicon { \"$link\": \"<cid>\" } object form."
+ },
+ "size": {
+ "description": "Size of the uploaded blob in bytes.",
+ "exclusiveMinimum": 0,
+ "type": "integer"
+ },
+ "type": {
+ "const": "blob",
+ "description": "Discriminator emitted by upload_image; always \"blob\" when present. May be omitted.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "ref",
+ "mimeType",
+ "size"
+ ],
+ "type": "object"
+}
addedInput schema / properties / embed / properties / external / properties / title / description
Added value: +"Title shown on the external link card (max 300 characters)."
addedInput schema / properties / embed / properties / external / properties / uri / description
Added value: +"The URL the external link card points to."
addedInput schema / properties / embed / properties / images / description
Added value: +"Up to 4 images to attach. Mutually exclusive with `external` and `quote`."
addedInput schema / properties / embed / properties / images / items / properties / alt / description
Added value: +"Accessibility alt text describing the image (max 1000 characters)."
addedInput schema / properties / embed / properties / images / items / properties / image / additionalProperties
Added value: +false
addedInput schema / properties / embed / properties / images / items / properties / image / description
Added value: +"Pre-uploaded image blob descriptor: pass the `image.blob` object from a prior upload_image call verbatim. The image must already be uploaded — this tool does not accept raw image data."
addedInput schema / properties / embed / properties / images / items / properties / image / properties
Added value: +{
+ "mimeType": {
+ "description": "MIME type of the uploaded blob (e.g. \"image/jpeg\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ "ref": {
+ "anyOf": [
+ {
+ "description": "CID of the uploaded blob as a flat string (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "additionalProperties": false,
+ "description": "Lexicon blob-ref object wrapping the CID as { \"$link\": \"<cid>\" }.",
+ "properties": {
+ "$link": {
+ "description": "CID of the uploaded blob (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "$link"
+ ],
+ "type": "object"
+ }
+ ],
+ "description": "CID reference of the uploaded blob: either the flat string returned by upload_image, or the lexicon { \"$link\": \"<cid>\" } object form."
+ },
+ "size": {
+ "description": "Size of the uploaded blob in bytes.",
+ "exclusiveMinimum": 0,
+ "type": "integer"
+ },
+ "type": {
+ "const": "blob",
+ "description": "Discriminator emitted by upload_image; always \"blob\" when present. May be omitted.",
+ "type": "string"
+ }
+}
addedInput schema / properties / embed / properties / images / items / properties / image / required
Added value: +[
+ "ref",
+ "mimeType",
+ "size"
+]
addedInput schema / properties / embed / properties / images / items / properties / image / type
Added value: +"object"
changedInput schema / properties / embed / properties / images / items / required
Previous value: -[
- "alt"
-]New value: +[
+ "alt",
+ "image"
+]
addedInput schema / properties / embed / properties / video
Added value: +{
+ "additionalProperties": false,
+ "description": "A video to attach (app.bsky.embed.video). Mutually exclusive with `images`, `external`, and `quote`.",
+ "properties": {
+ "alt": {
+ "description": "Accessibility alt text describing the video (max 1000 characters).",
+ "maxLength": 1000,
+ "type": "string"
+ },
+ "aspectRatio": {
+ "additionalProperties": false,
+ "description": "Optional aspect ratio hint (e.g. {\"width\": 16, \"height\": 9}) clients use to reserve layout space before the video loads.",
+ "properties": {
+ "height": {
+ "description": "Height component of the aspect ratio.",
+ "minimum": 1,
+ "type": "integer"
+ },
+ "width": {
+ "description": "Width component of the aspect ratio.",
+ "minimum": 1,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "width",
+ "height"
+ ],
+ "type": "object"
+ },
+ "captions": {
+ "description": "Up to 20 caption tracks, each pairing a language code with a pre-uploaded .vtt caption blob descriptor.",
+ "items": {
+ "additionalProperties": false,
+ "properties": {
+ "file": {
+ "additionalProperties": false,
+ "description": "Pre-uploaded WebVTT caption blob descriptor: pass a `video.captions[].file` object from upload_video verbatim.",
+ "properties": {
+ "mimeType": {
+ "description": "MIME type of the uploaded blob (e.g. \"image/jpeg\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ "ref": {
+ "anyOf": [
+ {
+ "description": "CID of the uploaded blob as a flat string (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "additionalProperties": false,
+ "description": "Lexicon blob-ref object wrapping the CID as { \"$link\": \"<cid>\" }.",
+ "properties": {
+ "$link": {
+ "description": "CID of the uploaded blob (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "$link"
+ ],
+ "type": "object"
+ }
+ ],
+ "description": "CID reference of the uploaded blob: either the flat string returned by upload_image, or the lexicon { \"$link\": \"<cid>\" } object form."
+ },
+ "size": {
+ "description": "Size of the uploaded blob in bytes.",
+ "exclusiveMinimum": 0,
+ "type": "integer"
+ },
+ "type": {
+ "const": "blob",
+ "description": "Discriminator emitted by upload_image; always \"blob\" when present. May be omitted.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "ref",
+ "mimeType",
+ "size"
+ ],
+ "type": "object"
+ },
+ "lang": {
+ "description": "BCP-47 language code for the caption track (e.g. \"en\", \"fr\", \"pt-BR\").",
+ "minLength": 2,
+ "type": "string"
+ }
+ },
+ "required": [
+ "lang",
+ "file"
+ ],
+ "type": "object"
+ },
+ "maxItems": 20,
+ "type": "array"
+ },
+ "video": {
+ "additionalProperties": false,
+ "description": "Pre-uploaded PROCESSED video blob descriptor: pass the `video.blob` object from a prior upload_video call verbatim. The video must already have been uploaded and processed by the video service — this tool does not accept raw video data.",
+ "properties": {
+ "mimeType": {
+ "description": "MIME type of the uploaded blob (e.g. \"image/jpeg\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ "ref": {
+ "anyOf": [
+ {
+ "description": "CID of the uploaded blob as a flat string (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ },
+ {
+ "additionalProperties": false,
+ "description": "Lexicon blob-ref object wrapping the CID as { \"$link\": \"<cid>\" }.",
+ "properties": {
+ "$link": {
+ "description": "CID of the uploaded blob (e.g. \"bafkrei…\").",
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "$link"
+ ],
+ "type": "object"
+ }
+ ],
+ "description": "CID reference of the uploaded blob: either the flat string returned by upload_image, or the lexicon { \"$link\": \"<cid>\" } object form."
+ },
+ "size": {
+ "description": "Size of the uploaded blob in bytes.",
+ "exclusiveMinimum": 0,
+ "type": "integer"
+ },
+ "type": {
+ "const": "blob",
+ "description": "Discriminator emitted by upload_image; always \"blob\" when present. May be omitted.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "ref",
+ "mimeType",
+ "size"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "video"
+ ],
+ "type": "object"
+}
addedInput schema / properties / facets
Added value: +{
+ "description": "Optional explicit richtext facets (byte-range annotations). For mentions, `value` is a handle or DID; for links, a URL; for hashtags, the tag without #. Omit to let the server auto-detect facets from the text.",
+ "items": {
+ "additionalProperties": false,
+ "properties": {
+ "features": {
+ "description": "One or more features applied to the annotated span.",
+ "items": {
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "description": "The kind of richtext feature this span represents.",
+ "enum": [
+ "mention",
+ "link",
+ "hashtag"
+ ],
+ "type": "string"
+ },
+ "value": {
+ "description": "For a mention: a handle or DID (a leading @ is stripped); for a link: the URL; for a hashtag: the tag (a leading # is stripped).",
+ "type": "string"
+ }
+ },
+ "required": [
+ "type",
+ "value"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "index": {
+ "additionalProperties": false,
+ "description": "UTF-8 byte range of the text span this facet annotates.",
+ "properties": {
+ "byteEnd": {
+ "description": "End byte offset (UTF-8) of the annotated span, exclusive.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "byteStart": {
+ "description": "Start byte offset (UTF-8) of the annotated span, inclusive.",
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "byteStart",
+ "byteEnd"
+ ],
+ "type": "object"
+ }
+ },
+ "required": [
+ "index",
+ "features"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+}
addedInput schema / properties / langs / description
Added value: +"Optional BCP-47 language tags (e.g. en, en-US, pt-BR) declaring the languages of the post text."
addedInput schema / properties / quote
Added value: +{
+ "additionalProperties": false,
+ "description": "Quote another post (record embed). Mutually exclusive with the `embed.images`, `embed.external`, and `embed.video` embeds.",
+ "properties": {
+ "cid": {
+ "description": "CID (content hash) of the quoted post.",
+ "minLength": 1,
+ "type": "string"
+ },
+ "uri": {
+ "description": "AT-URI of the post to quote.",
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "uri",
+ "cid"
+ ],
+ "type": "object"
+}
addedInput schema / properties / quoteControls
Added value: +{
+ "additionalProperties": false,
+ "description": "Quote (embed) policy for this post. Only allowQuotes:false writes an app.bsky.feed.postgate record, AFTER the post is created. If that write fails after the post succeeded, the call still succeeds with gateApplied:false and a warning instead of failing.",
+ "properties": {
+ "allowQuotes": {
+ "description": "Set false to disable quoting/embedding of this post: writes an app.bsky.feed.postgate record (same rkey as the post) with a disableRule. true is the network default — quoting stays enabled and no postgate record is written.",
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "allowQuotes"
+ ],
+ "type": "object"
+}
addedInput schema / properties / reply / description
Added value: +"Set to make this post a reply in an existing thread."
addedInput schema / properties / reply / properties / parent / description
Added value: +"AT-URI of the immediate parent post being replied to."
addedInput schema / properties / reply / properties / root / description
Added value: +"AT-URI of the root post of the thread being replied to."
addedInput schema / properties / replyControls
Added value: +{
+ "additionalProperties": false,
+ "description": "Who can reply to this post. Writes an app.bsky.feed.threadgate record (same rkey as the post) AFTER the post is created. Enabled options combine, up to 5 rules. Provide the object with NO rules enabled to let nobody reply; omit it entirely to leave replies open to everyone. If the gate write fails after the post succeeded, the call still succeeds with gateApplied:false and a warning instead of failing.",
+ "properties": {
+ "allowFollowers": {
+ "description": "Allow replies from accounts that follow the author (threadgate followerRule).",
+ "type": "boolean"
+ },
+ "allowFollowing": {
+ "description": "Allow replies from accounts the author follows (threadgate followingRule).",
+ "type": "boolean"
+ },
+ "allowListUris": {
+ "description": "Allow replies from members of these moderation/curation lists (threadgate listRule). Each entry must be the AT-URI of an app.bsky.graph.list record (at://did/app.bsky.graph.list/rkey); anything else is rejected before the post is created.",
+ "items": {
+ "description": "AT-URI of an app.bsky.graph.list record whose members may reply.",
+ "minLength": 1,
+ "type": "string"
+ },
+ "maxItems": 5,
+ "type": "array"
+ },
+ "allowMentioned": {
+ "description": "Allow replies from accounts @-mentioned in the post text (threadgate mentionRule).",
+ "type": "boolean"
+ }
+ },
+ "type": "object"
+}
addedInput schema / properties / text / description
Added value: +"The post body. Max 300 graphemes / 3000 bytes (emoji count as one grapheme). Mentions, links and #hashtags are auto-detected into richtext facets unless you supply `facets` explicitly."
changedInput schema / properties / text / maxLength
Previous value: -300New value: +3000
changedOutput schema / (root)
Previous value: -nullNew value: +{
+ "properties": {
+ "cid": {
+ "description": "CID (content hash) of the newly created post.",
+ "type": "string"
+ },
+ "gateApplied": {
+ "description": "Present only when replyControls and/or quoteControls were requested. True when every requested gate record (threadgate/postgate) is in effect. False when the post was created but a gate write failed — the post is LIVE without the requested controls (success stays true; see `warning` for which gate failed and how to retry).",
+ "type": "boolean"
+ },
+ "message": {
+ "description": "Human-readable status message.",
+ "type": "string"
+ },
+ "success": {
+ "description": "Whether the post was created successfully.",
+ "type": "boolean"
+ },
+ "uri": {
+ "description": "AT-URI of the newly created post.",
+ "type": "string"
+ },
+ "warning": {
+ "description": "Present only when gateApplied is false: explains which gate record (threadgate and/or postgate) could not be written and how to retry. The post itself was created successfully.",
+ "type": "string"
+ }
+ },
+ "required": [
+ "uri",
+ "cid",
+ "success",
+ "message"
+ ],
+ "type": "object"
+}