MCP (streamable HTTP) · Bluesky

Post to Bluesky from Windsurf, with approval

Windsurf's Cascade agent works across a whole codebase, so it can see the shape of a week's work, not just one file. Ask it for a weekly build-in-public update and it drafts a Bluesky thread through SocialHandoff: what shipped, what broke, what is next. Each post fits 300 graphemes, and you approve the thread as one unit. Nothing reaches Bluesky until you approve it in the inbox.

Prompt

Look at the commits on main from the last 7 days and draft a build-in-public Bluesky thread for my solo SaaS: post 1 what shipped, post 2 one thing that broke and how I fixed it, post 3 what I am building next week. Casual tone, no hashtags.

How to do it

  1. Mint a Bluesky agent key In https://app.socialhandoff.com, open Connections, connect your Bluesky account, then create an agent key scoped to Bluesky with draft permission only. Copy the key when it is shown; only its hash is stored.
  2. Edit mcp_config.json Open Windsurf's MCP settings and add a server with serverUrl https://app.socialhandoff.com/mcp and an Authorization header holding the Bluesky key. Or use the stdio form with npx -y socialhandoff-mcp.
  3. Refresh the servers Refresh MCP servers in the Cascade panel so the new tools load.
  4. Let Cascade draft Ask Cascade to summarize the branch you are on as a Bluesky post. It calls draft_post; you approve or send it back with edits from the inbox.

Example draft

1/3 Week 14 of building in public. Shipped: CSV import, finally. Drag in a file, map columns, done. It was the most requested thing in the feedback box.

2/3 What broke: a background job retried failed imports forever and ran up my queue bill. Fixed with a max of 5 attempts and a dead-letter table.

3/3 Next week: team invites, so two people can share one account.

Gotchas

  • Links, @handles, and #tags become clickable facets when the post publishes. Have the agent write the plain URL and handle, not markdown links.
  • Connect Bluesky with an app password from Settings, never your account password. Revoking that app password cuts off only this connection.
  • The 300 limit counts graphemes, so an emoji or accented letter counts as one. Anything longer should become a reply-chain thread, not a clipped post.
  • Windsurf loads MCP servers when Cascade starts. After changing mcp_config.json, refresh the servers or the Bluesky tools will not be offered.
Bluesky
  • Character limit: 300 graphemes per post. An emoji or an accented letter counts as 1 grapheme even if it uses several bytes.
  • Media per post: Up to 4 images, or 1 video. Images and video cannot be mixed in one post.
  • Image size: The AT Protocol image embed accepts blobs of about 1 MB each; the official app compresses larger photos. SocialHandoff checks for 1 MB per image.
  • Video: Up to 3 minutes and 100 MB, MP4. SocialHandoff does not publish video to Bluesky.
Bluesky scheduler for agent-drafted posts and threads

Frequently asked questions

Stdio or HTTP for Windsurf?
Both are supported. HTTP needs no local Node process. Stdio with npx -y socialhandoff-mcp is handy when your instance runs on the same machine.
Will Windsurf link to my repo correctly on Bluesky?
Yes. Write the plain URL and it becomes a clickable link facet when the post publishes. The same happens for @handles and #tags.
Is there a character counter for Bluesky?
Yes. The free Bluesky character counter on this site counts graphemes the way Bluesky does, and the length guardrail applies the same rule to every draft.

Let your agents post. Keep the final say.

Connect your first agent in minutes. Every draft waits in your inbox until you approve it.

14 days free. No card required.

The hosted version is opening soon

Leave your email and we will send one message when hosted accounts open, with your 14-day trial ready. Want it today? Self-host it free from the repo.

Start free trial