Give your own AI agent ThreadMaster tools

Connect a remote MCP server or wrap three REST calls with approval and retry guardrails.

Who it's for

Developers adding drafting, preview and approved publishing to their own agent framework.

What you'll have

A remote MCP connection or three Python tool functions with a publishing schema and human approval boundary.

Before you start

  • An active subscription, a connected X account and a scoped API key from Settings → Developer API.
  • A framework supporting remote HTTP MCP with a Bearer header, or Python 3 with requests installed for REST tools.
  • A host application that can obtain human approval and persist a UUID per approved publication.

Build the workflow

  1. Option A: connect remote MCP

    Configure this endpoint and Bearer API key to give your framework access to ThreadMaster tools over remote MCP. The JSON follows Cursor's setup; adapt the outer configuration to your framework and protect the secret.

    {
      "mcpServers": {
        "threadmaster": {
          "url": "https://threadmaster.ai/api/public/v1/mcp/",
          "headers": { "Authorization": "Bearer tm_live_YOUR_KEY" }
        }
      }
    }
  2. Option B: wrap three REST calls

    Expose generate_thread(topic), preview_x_thread(thread_id) and publish_to_x(thread_id, scheduled_for) as tools, with THREADMASTER_API_KEY set in the environment. The host supplies an approved publication UUID so the model reuses the same key on retries.

    import os, logging, requests
    from uuid import UUID
    
    BASE = "https://threadmaster.ai/api/public/v1"
    def request(method, path, **kwargs):
        headers = {"Authorization": "Bearer " + os.environ["THREADMASTER_API_KEY"]}
        headers.update(kwargs.pop("headers", {}))
        response = requests.request(method, BASE + path, headers=headers, timeout=90, **kwargs)
        logging.info("X-RateLimit-Remaining=%s", response.headers.get("X-RateLimit-Remaining"))
        response.raise_for_status()
        return response.json()
    
    def generate_thread(topic):
        return request("POST", "/threads/generate/", json={"topic": topic})
    
    def preview_x_thread(thread_id):
        return request("GET", f"/threads/{thread_id}/x/preview/")
    
    def approved_publish_tool(approved_id, approved_time, publication_key):
        key = str(UUID(publication_key))  # Load the persisted UUID from your host
        def publish_to_x(thread_id, scheduled_for):
            if (thread_id, scheduled_for) != (approved_id, approved_time):
                raise PermissionError("This publication has not been approved")
            return request("POST", "/x/posts/", json={
                "thread_id": thread_id, "scheduled_for": scheduled_for
            }, headers={"Idempotency-Key": key})
        return publish_to_x
  3. Describe the publishing tool

    Pass this tool definition to your adapter so it knows the publishing inputs. The wrapper requires scheduled_for to make the time explicit; your host must enforce approval before calling the API.

    {
      "name": "publish_to_x",
      "description": "Schedule the reviewed X thread only after human approval.",
      "parameters": {
        "type": "object",
        "properties": {
          "thread_id": { "type": "integer" },
          "scheduled_for": {
            "type": "string",
            "format": "date-time",
            "description": "ISO-8601 with timezone, at least two minutes in the future"
          }
        },
        "required": ["thread_id", "scheduled_for"],
        "additionalProperties": false
      }
    }
  4. Enforce human approval in the host

    Show content, X preview and time for approval, then save exact arguments, content version and a UUID before enabling publishing. Require new approval after edits and check content before calling; log X-RateLimit-Remaining and pause or delay calls when the budget is low.

    1. Agent proposes a thread_id and scheduled_for.
    2. Host shows saved content, preview and time; human confirms.
    3. Host stores approved arguments, content version and a UUID.
    4. Host checks content is unchanged, then permits this exact call.
    5. REST: bind approved_publish_tool to the stored arguments and UUID.
       MCP: pass that UUID as publish_to_x's idempotency_key.
    6. On transport retry, reuse the stored arguments and UUID.

    A tool description alone is not an approval check. Your adapter owns the confirmation, content check and persistent publication record.

Do it from your assistant

Generate a thread about our latest release and show me its X preview. Suggest a publishing time with a timezone offset. Wait for my confirmation before publishing, and reuse the approved publication's idempotency key on retries.

Set up the MCP server →

Watch out for

  • Settings lets you choose threads:read, threads:write, publish:read, publish:write and webhooks:manage. Issue the agent only the scopes it needs; this three-tool workflow does not need webhooks:manage.
  • Require human confirmation before any publish tool. Keep approval enforcement and idempotency keys in the host application.
  • Use the Bearer header for MCP. scheduled_for must be at least two minutes ahead, and the API's quotas and rate limits still apply.

Check the API rate limits and quotas before running your workflow at scale.

Get started

Write your next Twitter thread or LinkedIn post today

Sign up in under a minute. $9 a month, cancel anytime.

Get started →