Skip to main content
Glama
cameronrye

AT Protocol MCP Server

create_thread

Publish 2 to 25 posts as a threaded conversation, with each post automatically linked as a reply to the prior one. Use for multi-post content instead of individual posts.

Instructions

Create a thread of 2–25 posts in a single operation, automatically chaining each post as a reply to the previous one so readers see them as a continuous conversation. Use this instead of repeated create_post calls when content spans multiple posts; use create_post for a single standalone post or reply_to_post to append to an existing thread. Optional replyControls gate who can reply (a threadgate record on the ROOT post, written after the whole thread is published). Requires authentication (app password). If publishing fails mid-thread, already-published posts are returned with a failedAtPosition indicator so you can delete or resume them. Subject to per-tool rate limiting.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
postsYesOrdered array of posts to publish as a thread (2–25 items). Each post is automatically chained as a reply to the previous one.
langsNoDefault language tags (BCP-47) applied to every post in the thread. Individual posts can override this with their own langs field.
replyControlsNoWho can reply to the thread. Applies to the ROOT post only: a single app.bsky.feed.threadgate record is written with the root post’s rkey, AFTER every post in the thread is published (the in-thread replies are your own posts, created before the gate exists, so they are unaffected). Enabled options combine, up to 5 rules; provide the object with NO rules enabled to let nobody reply; omit it to leave replies open. If the gate write fails after the posts succeeded, the call still succeeds with gateApplied:false and a warning instead of failing.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
successYesTrue when all posts were published; false when only some posts were created before a failure.
messageYesHuman-readable summary of the outcome, including partial-failure details when applicable.
threadYesOrdered list of every post that was successfully published.
rootPostYesURI and CID of the root (first) post, which anchors the entire thread.
totalPostsYesNumber of posts actually published (may be less than requested if an error occurred mid-thread).
failedAtPositionNo1-based position of the post that failed; present only when success is false.
gateAppliedNoPresent only when replyControls were provided. True when the threadgate record was written on the root post (it is written after the whole thread is published, and is still attempted on the live root if the thread partially fails). False when the posts were published but the gate write failed — replies are then OPEN; see `warning`.
warningNoPresent only when gateApplied is false: explains that the threadgate write failed and how to retry. The published posts themselves are unaffected.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv0.6.2
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / posts / items / additionalProperties
      Removed value: -false
    • removedInput schema / properties / replyControls / additionalProperties
      Removed value: -false
  2. Changed9 schema fields changedv0.6.0
    • addedInput schema / properties / langs / description
      Added value: +"Default language tags (BCP-47) applied to every post in the thread. Individual posts can override this with their own langs field."
    • addedInput schema / properties / langs / items / description
      Added value: +"BCP-47 language tag (e.g. \"en\", \"en-US\", \"pt-BR\")."
    • addedInput schema / properties / posts / description
      Added value: +"Ordered array of posts to publish as a thread (2–25 items). Each post is automatically chained as a reply to the previous one."
    • addedInput schema / properties / posts / items / properties / langs / description
      Added value: +"Per-post language tags (BCP-47). When set, overrides the thread-level langs field for this individual post."
    • addedInput schema / properties / posts / items / properties / langs / items / description
      Added value: +"BCP-47 language tag for this post (e.g. \"en\", \"en-US\", \"pt-BR\"). Overrides the thread-level langs for this post only."
    • addedInput schema / properties / posts / items / properties / text / description
      Added value: +"Text content of this post (1–300 graphemes / 3000 bytes). Mentions (@handle), URLs, and hashtags are auto-linked via richtext facets."
    • changedInput schema / properties / posts / items / properties / text / maxLength
      Previous value: -300New value: +3000
    • addedInput schema / properties / replyControls
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "Who can reply to the thread. Applies to the ROOT post only: a single app.bsky.feed.threadgate record is written with the root post’s rkey, AFTER every post in the thread is published (the in-thread replies are your own posts, created before the gate exists, so they are unaffected). Enabled options combine, up to 5 rules; provide the object with NO rules enabled to let nobody reply; omit it to leave replies open. If the gate write fails after the posts 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"
      +}
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "failedAtPosition": {
      +      "description": "1-based position of the post that failed; present only when success is false.",
      +      "type": "number"
      +    },
      +    "gateApplied": {
      +      "description": "Present only when replyControls were provided. True when the threadgate record was written on the root post (it is written after the whole thread is published, and is still attempted on the live root if the thread partially fails). False when the posts were published but the gate write failed — replies are then OPEN; see `warning`.",
      +      "type": "boolean"
      +    },
      +    "message": {
      +      "description": "Human-readable summary of the outcome, including partial-failure details when applicable.",
      +      "type": "string"
      +    },
      +    "rootPost": {
      +      "description": "URI and CID of the root (first) post, which anchors the entire thread.",
      +      "properties": {
      +        "cid": {
      +          "description": "CID of the root post record.",
      +          "type": "string"
      +        },
      +        "uri": {
      +          "description": "AT-URI of the root post.",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "uri",
      +        "cid"
      +      ],
      +      "type": "object"
      +    },
      +    "success": {
      +      "description": "True when all posts were published; false when only some posts were created before a failure.",
      +      "type": "boolean"
      +    },
      +    "thread": {
      +      "description": "Ordered list of every post that was successfully published.",
      +      "items": {
      +        "properties": {
      +          "cid": {
      +            "description": "Content identifier (CID) of the published post record.",
      +            "type": "string"
      +          },
      +          "isRoot": {
      +            "description": "True only for the first post (the thread root).",
      +            "type": "boolean"
      +          },
      +          "position": {
      +            "description": "1-based index of this post within the thread.",
      +            "type": "number"
      +          },
      +          "text": {
      +            "description": "Original text content of this post.",
      +            "type": "string"
      +          },
      +          "uri": {
      +            "description": "AT-URI of the published post (at://did/app.bsky.feed.post/rkey).",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "uri",
      +          "cid",
      +          "text",
      +          "position",
      +          "isRoot"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "totalPosts": {
      +      "description": "Number of posts actually published (may be less than requested if an error occurred mid-thread).",
      +      "type": "number"
      +    },
      +    "warning": {
      +      "description": "Present only when gateApplied is false: explains that the threadgate write failed and how to retry. The published posts themselves are unaffected.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "success",
      +    "message",
      +    "thread",
      +    "rootPost",
      +    "totalPosts"
      +  ],
      +  "type": "object"
      +}
  3. Changed7 schema fields changedv0.3.0
    • removedInput schema / $schema
      Removed value: -"http://json-schema.org/draft-07/schema#"
    • removedInput schema / properties / langs / items / maxLength
      Removed value: -2
    • removedInput schema / properties / langs / items / minLength
      Removed value: -2
    • addedInput schema / properties / langs / items / pattern
      Added value: +"^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$"
    • removedInput schema / properties / posts / items / properties / langs / items / maxLength
      Removed value: -2
    • removedInput schema / properties / posts / items / properties / langs / items / minLength
      Removed value: -2
    • addedInput schema / properties / posts / items / properties / langs / items / pattern
      Added value: +"^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$"
  4. First observedv0.2.1

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds significant behavioral context beyond annotations: auto-chaining, partial failure handling with failedAtPosition, threadgate writing after publication, and rate limiting. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Concise paragraph with front-loaded purpose. Every sentence adds value – no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Comprehensive for a tool with 3 params and nested objects. Covers partial failure, authentication, rate limiting, and sibling differentiation. Output schema exists, so return values are covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% description coverage, so baseline is 3. The description adds extra semantics like chaining behavior, replyControls timing, and failure handling, earning a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it creates a thread of 2-25 posts, auto-chaining them, and distinguishes from create_post and reply_to_post.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool versus alternatives (create_post for single posts, reply_to_post for appending to existing threads). Also mentions authentication and optional replyControls.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.