threads_publish_image
Publish image posts on Threads with captions, topic tags, alt text, and reply controls. Supports quoting posts and marking content as spoilers.
Instructions
Publish an image post on Threads. Supports topic tag, quote post, alt text, and spoiler flag.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| image_url | Yes | Public HTTPS URL of the image (JPEG/PNG, max 8MB) | |
| text | No | Caption text | |
| reply_control | No | Who can reply | |
| topic_tag | No | Topic tag for the post | |
| quote_post_id | No | ID of a post to quote | |
| alt_text | No | Alt text for accessibility (max 1000 chars) | |
| is_spoiler | No | Mark content as spoiler |
Implementation Reference
- src/tools/threads/publishing.ts:63-94 (handler)The 'threads_publish_image' tool is defined here, taking image_url, text, and other optional parameters, creating a Threads media container, and then publishing it.
server.tool( "threads_publish_image", "Publish an image post on Threads. Supports topic tag, quote post, alt text, and spoiler flag.", { image_url: z.string().url().describe("Public HTTPS URL of the image (JPEG/PNG, max 8MB)"), text: z.string().max(500).optional().describe("Caption text"), reply_control: z.enum(["everyone", "accounts_you_follow", "mentioned_only", "parent_post_author_only", "followers_only"]).optional().describe("Who can reply"), topic_tag: z.string().max(50).optional().describe("Topic tag for the post"), quote_post_id: z.string().optional().describe("ID of a post to quote"), alt_text: z.string().max(1000).optional().describe("Alt text for accessibility (max 1000 chars)"), is_spoiler: z.boolean().optional().describe("Mark content as spoiler"), }, async ({ image_url, text, reply_control, topic_tag, quote_post_id, alt_text, is_spoiler }) => { try { const params: Record<string, unknown> = { media_type: "IMAGE", image_url }; if (text) params.text = text; if (reply_control) params.reply_control = reply_control; if (topic_tag) params.topic_tag = topic_tag; if (quote_post_id) params.quote_post_id = quote_post_id; if (alt_text) params.alt_text = alt_text; if (is_spoiler) params.is_spoiler_media = true; const { data: container } = await client.threads("POST", `/${client.threadsUserId}/threads`, params); const containerId = (container as { id: string }).id; const { data, rateLimit } = await client.threads("POST", `/${client.threadsUserId}/threads_publish`, { creation_id: containerId, }); return { content: [{ type: "text", text: JSON.stringify({ ...data as object, _rateLimit: rateLimit }, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Publish image failed: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } } );