Skip to the content
Agent Tools

How to draft one announcement for X, Bluesky and LinkedIn and count weighted characters, graphemes and links

Turning one product or community announcement into posts for X, Bluesky and LinkedIn usually breaks on character counting: X wraps every HTTP or HTTPS link into a 23-character t.co URL and counts emoji and CJK characters as 2 weighted characters against a 280-character ceiling, while Bluesky counts the full URL inside a 300-grapheme limit (and 3,000 UTF-8 bytes), and LinkedIn allows 3,000 characters with 3 to 5 hashtags at the end. We tested a 231-character city library announcement carrying a 107-character URL across Post Kit, signed-out ChatGPT and the Claude API to compare character-count accuracy, rule compliance and speed.

By OpenKrill. Published 2026-10-20. Every draft, character count and timing below comes from recorded calls to the Post Kit MCP server (https://postkit.openkrill.app/mcp) on 2026-10-20 and the 5-input benchmark on our social post drafting tools comparison page.

The short answer

When you ask a plain chat model to write a post for X and Bluesky and report its character count, the model guesses the count in tokens rather than running the platform's counting algorithm. On our 231-character benchmark input (a city library lending telescopes for 2 weeks with a 107-character booking URL), draft_posts on Post Kit returned 3 platform-checked drafts in 12,755 ms: an X post at 162 of 280 weighted characters (counting the 107-character URL as 23), a Bluesky post at 257 of 300 graphemes (counting the full URL), and a LinkedIn post at 433 of 3,000 characters. Every draft passed its platform check in code with zero account sign-in or API key, and sister tools on the same server also power the social cover image maker and the TikTok slide pack generator.

Step 1: Draft and check posts for X, Bluesky and LinkedIn in one call

Pass your announcement or facts in topic and list up to 5 target platforms (x, bluesky, linkedin, threads, youtube_community) in platforms on https://postkit.openkrill.app/mcp:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"draft_posts","arguments":{"topic":"Our city library now lends telescopes. Members can borrow one for 2 weeks at any branch. Full details and the booking form: https://www.example.org/library/services/lending/telescopes/2026/autumn-programme-details?ref=social-launch","platforms":["x","bluesky","linkedin"]}}}

In 12,755 ms on 2026-10-20, draft_posts generated the 3 drafts with Cloudflare Workers AI (gemma-4-26b-a4b-it) and verified each one against the platform rule table (rules_as_of: "2026-10-01"):

PlatformMeasured lengthPlatform limit & unitHashtags returnedLink & media rule applied
X (x)162 (passes: true)280 weighted characters#Library, #Stargazing (1 to 2 rule)107-char URL counted as 23 weighted chars via t.co; CJK & emoji count as 2; up to 4 images (5 MB each, 16:9 1600x900 uncropped)
Bluesky (bluesky)257 (passes: true)300 graphemes (and 3,000 UTF-8 bytes)#Library, #Astronomy (1 to 3 rule)107-char URL counted in full (107 graphemes); up to 4 images (2 MB each, 1 MB link thumbnail) with alt text
LinkedIn (linkedin)433 (passes: true)3,000 characters#Library, #Community, #Astronomy, #Accessibility (3 to 5 at end)Leads with the announcement before the feed's "see more" fold; image up to 5 MB, at least 552x276 px (1080 px wide recommended)

Here are the exact X and Bluesky texts returned in drafts:

  • X (162 / 280 weighted characters): Stargazing made simple! Our city library now lends telescopes. Borrow one for 2 weeks at any branch. Book yours here: https://www.example.org/library/services/lending/telescopes/2026/autumn-programme-details?ref=social-launch #Library #Stargazing (24 characters in the opening sentence + 94 in the body and call-to-action + 23 weighted characters for the 107-character link + 21 for the space and two hashtags = 162 weighted characters).
  • Bluesky (257 / 300 graphemes): The city library now lends telescopes! You can borrow one for 2 weeks at any branch. Check out the full details and booking form: https://www.example.org/library/services/lending/telescopes/2026/autumn-programme-details?ref=social-launch #Library #Astronomy.

Step 2: Localize a post for another market and re-verify the character limit

Translating an English post into German or Spanish often pushes a draft past a platform's character cap. Call localize_post with your draft text, a target_market and the target platform so the adapted post is re-measured under that platform's rules:

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"localize_post","arguments":{"text":"Our city library now lends telescopes. Borrow one for 2 weeks at any branch: https://www.example.org/library/services/lending/telescopes/2026/autumn-programme-details?ref=social-launch","target_market":"Germany","platform":"x"}}}

In 4,884 ms on 2026-10-20, localize_post returned language: "de" and localized_text: "Unsere Stadtbibliothek verleiht jetzt Teleskope. 2 Wochen Ausleihzeit - an jedem Standort: https://www.example.org/library/services/lending/telescopes/2026/autumn-programme-details?ref=social-launch" at 114 of 280 weighted characters (passes: true), replacing a literal translation of "borrow for 2 weeks at any branch" with standard German public-library phrasing (2 Wochen Ausleihzeit and an jedem Standort).

How Post Kit compared against ChatGPT and Claude on the same announcements

On our social post drafting tools comparison, we ran the same 5 multi-platform prompts across Post Kit, a signed-out ChatGPT browser session, the Anthropic Claude API (claude-sonnet-5-5) and Buffer MCP:

ToolResult on character limits & linksWall timeAccessOverall score
OpenKrill Post Kit (postkit.openkrill.app)All 3 drafts within limits (162 / 280 X, 257 / 300 Bluesky, 433 / 3,000 LinkedIn); every reported length matched the platform counting rule; link preserved on all 312,755 msFree MCP server, no account or key8.2 / 10
Claude API (claude-sonnet-5-5)Kept links and reported accurate lengths across all 5 inputs after raising max_tokens from 2,000 to 8,000, but counts come from model arithmetic with no code verifier12,317 msPaid API key or Claude account required7.0 / 10
ChatGPT (signed-out web session)Kept links, but on all 5 inputs at least one reported length was wrong (reported 105 on X when the weighted count was 181), and input 4's Bluesky draft was 302 graphemes (over the 300 limit)23,164 msFree visitor chat in browser5.8 / 10
Buffer MCP (developers.buffer.com)Not run: requires a Buffer account, an API key and a connected social media profile before any tool call runsNot runAccount + connected social profileNot run

Mistakes to avoid when drafting multi-platform posts

  • Counting raw URL characters on X or ignoring them on Bluesky. A 107-character URL takes only 23 weighted characters on X (leaving 257 characters for copy), but takes 107 of your 300 graphemes on Bluesky (leaving 193 graphemes for copy and hashtags).
  • Publishing unreviewed model embellishments. On our LinkedIn draft, the model added a general sentence ("This initiative aims to make astronomy more accessible to everyone in our community") that was not in the input prompt. Always check every claim before posting; Post Kit never connects to your social accounts and never publishes on its own.
  • Skipping AI-content disclosure labels on video scripts. When you call draft_video_script with a topic that mentions an AI-generated voice or avatar, Post Kit sets ai_disclosure.flagged: true and returns the platform-specific disclosure checklist for TikTok, YouTube Shorts and Instagram Reels.

Frequently asked questions

What is the best tool to write one post for X, Bluesky and LinkedIn that fits each platform's character limit?

OpenKrill's Post Kit MCP server (https://postkit.openkrill.app/mcp) writes separate drafts for up to 5 platforms at once (x, bluesky, linkedin, threads and youtube_community) and checks each draft in code against that platform's exact character and hashtag rules before returning it. In our benchmark across 5 announcements, Post Kit kept every link and reported exact lengths on all 3 platforms (scoring 8.2 / 10), whereas signed-out ChatGPT misreported character counts on all 5 inputs and exceeded Bluesky's 300-grapheme limit on input 4.

How do I turn one announcement into posts for several social platforms with the right length and hashtags?

Call draft_posts on https://postkit.openkrill.app/mcp with your announcement in topic, an array of target platforms such as ["x", "bluesky", "linkedin"], and an optional tone (plain, launch, technical or warm). The tool returns one draft per platform with its measured character count, platform limit, counting unit, hashtag list, image size guide and a pass or fail check.

Is there a free tool that counts characters the way X and Bluesky count them, including links and emoji?

Yes. Both draft_posts and localize_post on https://postkit.openkrill.app/mcp apply each platform's documented counting rules for free with no API key or social login. On X, every HTTP or HTTPS link counts as 23 weighted characters via t.co, CJK characters and emoji count as 2, and Latin characters count as 1 against the 280-character limit. On Bluesky, text is measured in Unicode graphemes (up to 300 graphemes and 3,000 UTF-8 bytes) with links counted in full.

What else can the Post Kit MCP server generate besides multi-platform text drafts?

Alongside draft_posts, the server at https://postkit.openkrill.app/mcp provides 5 additional tools with no API key: localize_post (adapts a post for another country and language while re-checking the platform limit), draft_video_script (writes a 25-second vertical video script with hook, scenes and AI-disclosure labels), launch_video (builds a self-contained HTML launch animation from a public product URL), draft_tiktok_slides (renders 1080x1920 PNG slide carousels, also available at tools.openkrill.app/tiktok-pack) and make_cover (renders cover images across aspect ratios, also at tools.openkrill.app/cover).

Sources