Skip to main content
Glama
brianellin

Bluesky MCP Server

by brianellin

create-post

Generate and publish a post on Bluesky, including text content up to 300 characters, with an optional reply to an existing post.

Instructions

Create a new post on Bluesky

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
replyToNoOptional URI of post to reply to
textYesThe content of your post

Implementation Reference

  • src/index.ts:212-266 (registration)
    Registration of the 'create-post' MCP tool, including inline schema and handler function.
    server.tool(
      "create-post",
      "Create a new post on Bluesky",
      {
        text: z.string().max(300).describe("The content of your post"),
        replyTo: z.string().optional().describe("Optional URI of post to reply to"),
      },
      async ({ text, replyTo }) => {
        if (!agent) {
          return mcpErrorResponse("Not connected to Bluesky. Check your environment variables.");
        }
    
        try {
          const record: any = {
            text,
            createdAt: new Date().toISOString(),
          };
    
          let replyRef;
          if (replyTo) {
            // Handle reply format
            try {
              const parts = replyTo.split('/');
              const did = parts[2];
              const rkey = parts[parts.length - 1];
              const collection = parts[parts.length - 2] === 'app.bsky.feed.post' ? 'app.bsky.feed.post' : parts[parts.length - 2];
              
              // Resolve the CID of the post we're replying to
              const cidResponse = await agent.app.bsky.feed.getPostThread({ uri: replyTo });
              if (!cidResponse.success) {
                throw new Error('Could not get post information');
              }
              
              const threadPost = cidResponse.data.thread as any;
              const parentCid = threadPost.post.cid;
              
              // Add reply information to the record
              record.reply = {
                parent: { uri: replyTo, cid: parentCid },
                root: { uri: replyTo, cid: parentCid }
              };
    
            } catch (error) {
              return mcpErrorResponse(`Error parsing reply URI: ${error instanceof Error ? error.message : String(error)}`);
            }
          }
    
          const response = await agent.post(record);
          
          return mcpSuccessResponse(`Post created successfully! URI: ${response.uri}`);
        } catch (error) {
          return mcpErrorResponse(`Error creating post: ${error instanceof Error ? error.message : String(error)}`);
        }
      }
    );
  • Zod input schema defining parameters for the create-post tool: required 'text' (max 300 chars) and optional 'replyTo' URI.
    {
      text: z.string().max(300).describe("The content of your post"),
      replyTo: z.string().optional().describe("Optional URI of post to reply to"),
    },
  • Handler function that authenticates with agent, constructs post record with optional reply context (fetches CID), posts via agent.post(), and returns success/error MCP response.
      async ({ text, replyTo }) => {
        if (!agent) {
          return mcpErrorResponse("Not connected to Bluesky. Check your environment variables.");
        }
    
        try {
          const record: any = {
            text,
            createdAt: new Date().toISOString(),
          };
    
          let replyRef;
          if (replyTo) {
            // Handle reply format
            try {
              const parts = replyTo.split('/');
              const did = parts[2];
              const rkey = parts[parts.length - 1];
              const collection = parts[parts.length - 2] === 'app.bsky.feed.post' ? 'app.bsky.feed.post' : parts[parts.length - 2];
              
              // Resolve the CID of the post we're replying to
              const cidResponse = await agent.app.bsky.feed.getPostThread({ uri: replyTo });
              if (!cidResponse.success) {
                throw new Error('Could not get post information');
              }
              
              const threadPost = cidResponse.data.thread as any;
              const parentCid = threadPost.post.cid;
              
              // Add reply information to the record
              record.reply = {
                parent: { uri: replyTo, cid: parentCid },
                root: { uri: replyTo, cid: parentCid }
              };
    
            } catch (error) {
              return mcpErrorResponse(`Error parsing reply URI: ${error instanceof Error ? error.message : String(error)}`);
            }
          }
    
          const response = await agent.post(record);
          
          return mcpSuccessResponse(`Post created successfully! URI: ${response.uri}`);
        } catch (error) {
          return mcpErrorResponse(`Error creating post: ${error instanceof Error ? error.message : String(error)}`);
        }
      }
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/brianellin/bsky-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server