AT Protocol MCP Server
This server acts as a bridge between LLM clients (like Claude Desktop) and the AT Protocol/Bluesky social network, enabling natural language interaction via 60 specialized MCP tools.
Post & Content Management
Create, reply to, and delete posts with rich text (mentions, links, hashtags)
Create multi-post threads (up to 25 posts), generate link previews
Upload images (JPEG, PNG, GIF, WebP) and videos (MP4, MOV, WebM)
Social Interactions
Like/unlike, repost/unrepost, quote-repost, follow/unfollow users
View profiles, follower/following lists, timelines, custom feeds, threads, and notifications
Batch Operations
Follow, like, or repost up to 25 items in a single call
Search & Discovery
Search posts by text, author, language, date range, domain, and more
Discover trending topics, similar users, influential voices, and communities
Get personalized content recommendations
Analytics & Insights
Analyze engagement patterns, network connections, and post performance
Get content strategy recommendations and moderation status analysis
List Management
Create curated or moderation lists, add/remove users
Moderation
Mute/unmute, block/unblock users, report content or accounts
Media Tools
Generate alt text for images, analyze image metadata, extract all media from a post or thread
Composite Operations
Get a full user summary (profile + posts + engagement) or full post context in one call
Authentication
Unauthenticated mode: access public profiles and follower/following lists
Authenticated mode (app passwords): full access including write operations and private data
Experimental Features
OAuth authorization flow initiation (token exchange not yet implemented)
Real-time firehose streaming with keyword/user monitoring (frame decoding not yet functional)
Provides tools for interacting with the Bluesky social network via the AT Protocol, including unauthenticated access to public data (view profiles, manage OAuth flows) and authenticated access for full functionality (search posts, create/like/repost, manage timelines, feeds, and notifications).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@AT Protocol MCP Server search for recent posts about AI"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AT Protocol MCP Server
A comprehensive Model Context Protocol (MCP) server that provides LLMs with direct access to the AT Protocol ecosystem, enabling seamless interaction with Bluesky and other AT Protocol-based social networks.
Supports both authenticated and unauthenticated modes - Start immediately with public data access (view profiles, search accounts, fetch follower/following lists), or add authentication for full functionality (search, write operations, private data, feeds).
Zero-config launch:
npx atproto-mcpruns the server in unauthenticated public-data mode — no credentials required.Recent additions: Bluesky direct messages, private bookmarks, starter pack discovery, reply/quote controls on posts, parameterized MCP resource templates, and an optional Streamable HTTP transport (
--transport http).
Architecture
This MCP server acts as a bridge between LLM clients and the AT Protocol ecosystem:
┌─────────────────┐
│ User │ "Search for posts about AI"
└────────┬────────┘
│ Natural Language
▼
┌─────────────────┐
│ LLM Client │ (Claude Desktop, etc.)
│ (MCP Client) │
└────────┬────────┘
│ MCP Protocol (JSON-RPC 2.0)
▼
┌─────────────────┐
│ This Server │ AT Protocol MCP Server
│ (MCP Server) │ - Tools, Resources, Prompts
└────────┬────────┘
│ AT Protocol API
▼
┌─────────────────┐
│ AT Protocol │ Bluesky, Custom PDS, etc.
│ Ecosystem │
└─────────────────┘Key Point: Users don't interact with this server directly. Instead, they talk to their LLM client in natural language, and the LLM client uses this MCP server to access AT Protocol functionality.
Related MCP server: Bluesky MCP Server
Features
Highlights
Batch Operations: Perform multiple operations in a single call (follow/like/repost up to 25 items at once)
Analytics & Insights: Analyze engagement patterns, network connections, and get content strategy recommendations
Content Discovery: Find similar users, trending topics, starter packs, and influential voices in your areas of interest
Direct Messages: List conversations, read message history, and send Bluesky DMs (requires a DM-enabled app password)
Private Bookmarks: Save, list, and remove private bookmarks on posts
Core Features
Zero-config Unauthenticated Mode: Run
npx atproto-mcpto access public data without any setup - view profiles, search accounts, and fetch follower/following listsOptional Authentication: Enable full functionality with app passwords for write operations, feeds, and private data
Complete AT Protocol Integration: Full implementation using official
@atproto/apiMCP Server Compliance: Built with
@modelcontextprotocol/sdkfollowing MCP specificationType-Safe: Written in TypeScript with strict type checking
Comprehensive Tools: 51 MCP tools for social networking operations
Rate Limiting: Built-in respect for AT Protocol rate limits
Extensible: Modular architecture for easy customization
Planned: OAuth login is on the roadmap but not yet functional — app-password authentication is the supported auth path today. Real-time firehose streaming is not planned as MCP tools: a request/response tool cannot honestly expose a continuous stream, and the unused firehose client code has been removed. If streaming ever ships it will be built fresh on Jetstream.
Who Is This For?
Primary Audience: LLM Clients
This is an MCP (Model Context Protocol) server designed to be consumed by LLM clients such as:
Claude Desktop
Other MCP-compatible AI assistants
Custom LLM applications using the MCP SDK
How it works:
User → LLM Client (Claude Desktop) → MCP Protocol → This Server → AT Protocol → BlueskyUsers interact with their LLM client in natural language (e.g., "search for posts about AI"), and the LLM client uses this MCP server to fulfill those requests by calling the appropriate tools via the MCP protocol.
Secondary Audience: Developers
This project is also for developers who want to:
Deploy the MCP server for their LLM clients to connect to
Extend the server with custom MCP tools and resources
Contribute to the open-source project
This Is NOT:
A direct-use REST API or SDK for application developers
A JavaScript/TypeScript library to import into your app
An end-user application
If you're building an application that needs AT Protocol functionality, you should either:
Use the official
@atproto/apipackage directly, ORBuild an LLM-powered application that uses this MCP server through an LLM client
Installation
Run it with no install and no configuration — npx atproto-mcp launches the
server in unauthenticated public-data mode immediately:
npx atproto-mcpOr install globally:
npm install -g atproto-mcpClaude Desktop
Add this to your Claude Desktop MCP configuration to run the server with zero config:
{
"mcpServers": {
"atproto": { "command": "npx", "args": ["-y", "atproto-mcp"] }
}
}Quick Start
Option 1: Unauthenticated Mode (Recommended for most use cases)
Perfect for LLM clients that need to access public AT Protocol data:
Configure your LLM client (e.g., Claude Desktop) to launch the MCP server:
Add to your LLM client's MCP configuration:
{ "mcpServers": { "atproto": { "command": "npx", "args": ["atproto-mcp"] } } }Start your LLM client - it will automatically launch the MCP server
Interact in natural language - Ask your LLM to search posts, view profiles, etc.
What your LLM can do in unauthenticated mode:
View user profiles (
get_user_profile- works without auth, provides additional viewer-specific data when authenticated)Search for accounts by handle or name (
search_actors)List a user's posts (
get_author_feed)View follower/following lists (
get_user_connectionswithdirection: 'followers' | 'follows'- ENHANCED mode: works without auth, enriches the underlying API call when authenticated)
Note: The following features require authentication:
Searching posts and hashtags (
search_posts) - API changed in 2025 to require authenticationBrowsing feeds and threads (
get_post_context,get_custom_feed,get_timeline)All write operations (create, like, repost, follow, etc.)
Resources (timeline, profile, notifications) - these are listed but require authentication to return data
Prompts (content composition, reply templates) are pure text templates and work without authentication.
Important: All tools, resources, and prompts are listed by the MCP server regardless of authentication state. Most tools and resources that require authentication will return a clear error message when called without proper credentials.
Option 2: Authenticated Mode (For full functionality)
Enable write operations and private data access for your LLM:
Configure your LLM client with AT Protocol credentials:
{ "mcpServers": { "atproto": { "command": "npx", "args": ["atproto-mcp"], "env": { "ATPROTO_IDENTIFIER": "your-handle.bsky.social", "ATPROTO_PASSWORD": "your-app-password" } } } }Start your LLM client - it will launch the authenticated MCP server
What your LLM can do in authenticated mode:
Create, edit, and delete posts
Follow/unfollow users
Like and repost content
Access personalized timelines and notifications
Manage lists and moderation settings
Available Tools
The server provides 51 MCP tools across multiple categories. See the complete API documentation for detailed information on each tool.
Public Tools (No Authentication Required)
Data Retrieval
get_user_profile- Retrieve basic user information (ENHANCED mode: works without auth, provides additional viewer-specific data when authenticated)get_user_summary- Get a profile with recent posts and engagement stats in one call (ENHANCED mode)search_actors- Find accounts by handle or display name (ENHANCED mode)get_author_feed- List a specific user's posts (ENHANCED mode)get_user_connections- Get follower or following lists viadirection: 'followers' | 'follows'(ENHANCED mode: works without auth, enriches the underlying API call when authenticated)get_post_context- Get a post with optional thread, author profile, engagement metrics, and media (ENHANCED mode)search_starter_packs/get_starter_pack- Search Bluesky starter packs by keyword and fetch a pack's details (ENHANCED mode)
Rich Media
analyze_image- Report blob-declared size and MIME type for an image (PUBLIC mode: no auth required; does not decode pixels, so no dimensions/aspect ratio)
Note: As of 2025, the AT Protocol API has changed to require authentication
for most endpoints that were previously public, including search_posts.
Private Tools (Authentication Required)
Social Operations
create_post- Create posts with text, auto-detected or explicit richtext facets, replies, image/external embeds, and quote postscreate_thread- Create multi-post threads in one callreply_to_post- Reply to existing posts with threadinglike_post/unlike_post- Like and unlike postsrepost/unrepost- Repost content with optional quotesfollow_user/unfollow_user- Follow and unfollow users
Data Retrieval
search_posts- Search for posts and content across the network (⚠️ API changed in 2025 to require auth)get_custom_feed- Access custom feedsget_timeline- Retrieve personalized timelinesget_notifications- Access notification feeds (usecountOnly: truefor a cheap unread badge count)mark_notifications_seen- Mark notifications as seen up to a timestamp
Direct Messages
list_conversations- List your Bluesky DM conversationsget_conversation_messages- Read a conversation's message historysend_direct_message- Send a DM (requires an app password created with "Allow access to your direct messages" enabled)
Bookmarks
add_bookmark/remove_bookmark- Privately bookmark and un-bookmark postsget_bookmarks- List your private bookmarks
Content Management
upload_image/upload_video- Upload media contentdelete_post- Remove postsupdate_profile- Modify profile and settingsgenerate_link_preview- Generate link previews for posts
List Management
create_list- Create user listsadd_to_list/remove_from_list- Manage list membersget_list- Retrieve list information
Moderation
mute_user/unmute_user- Mute and unmute usersblock_user/unblock_user- Block and unblock usersreport_content/report_user- Report content and usersanalyze_moderation_status- Check moderation status of content
Batch Operations
batch_action- Apply one action across up to 25 targets in a single call viaaction: 'follow' | 'like' | 'repost'
Analytics & Insights
analyze_account- Analyze a single account along one dimension viadimension: 'engagement' | 'network' | 'strategy'find_influential_users- Find influential users in a topic area
Content Discovery
discover- Surface timeline content viamode: 'trending' | 'recommended'find_similar_users- Find users similar to a given userdiscover_communities- Discover communities around topics
Documentation
Visit our documentation site for:
Getting Started Guide
API Reference
Configuration Options
Examples and Tutorials
Troubleshooting
Authentication (Optional)
The server works perfectly without authentication for accessing public data. Authentication is only needed for write operations and private data access.
App Passwords (Recommended for Development)
export ATPROTO_IDENTIFIER="your-handle.bsky.social"
export ATPROTO_PASSWORD="your-app-password"
atproto-mcpApp passwords are the supported authentication path. OAuth login is planned but not yet functional.
Development
Quick Start
# Clone the repository
git clone https://github.com/cameronrye/atproto-mcp.git
cd atproto-mcp
# Install dependencies (use pnpm, npm, or yarn)
pnpm install # or: npm install
# Start development server
pnpm dev # or: npm run dev
# Run tests
pnpm test # or: npm test
# Build for production
pnpm build # or: npm run buildAvailable Commands
This project provides cross-platform npm scripts that work on Windows, macOS, and Linux:
# Show all available commands
npm run help
# Development
npm run dev # Start development server with hot reload
npm run build # Build for production
npm run start # Start production server
# Testing & Quality
npm test # Run tests
npm run test:coverage # Run tests with coverage
npm run test:ui # Run tests with interactive UI
# Integration Tests (connects to real AT Protocol servers)
npm run test:integration
npm run lint # Run ESLint
npm run lint:fix # Fix linting issues
npm run format # Format code with Prettier
npm run type-check # Run TypeScript type checking
npm run check # Run all quality checks
# Utilities
npm run clean # Clean build artifacts
npm run clean:all # Clean everything including node_modules
npm run status # Show project status
npm run ci # Run full CI pipeline locally
# Dependencies
npm run deps:update # Update dependencies
npm run deps:audit # Audit for security issuesCross-Platform Compatibility
All build commands work on Windows, macOS, and Linux without requiring
additional tools. Simply use npm scripts on any platform (e.g., npm run dev,
npm test, npm run build).
Testing
The project includes comprehensive test coverage:
Unit Tests
# Run all unit tests
pnpm test
# Run with coverage
pnpm test:coverage
# Run with interactive UI
pnpm test:uiIntegration Tests
Comprehensive integration tests that connect to real AT Protocol servers to validate all public-facing functionality:
# Run integration tests (requires internet connection)
npm run test:integrationWhat's tested:
Public/enhanced tools (
get_user_profile,get_user_connections,get_author_feed) and authenticated tools (search_posts,get_post_context,get_custom_feed)DID and handle resolution
Pagination support
Error handling
AT Protocol specification compliance
Rate limiting behavior
Note: Integration tests are opt-in and disabled by default to avoid hitting real servers during normal development. See Integration Tests Documentation for details.
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Fork the repository
Create a feature branch
Make your changes
Add tests
Submit a pull request
License
This project is licensed under the MIT License.
Acknowledgments
AT Protocol Team for the excellent protocol and SDK
Anthropic for the Model Context Protocol
The open source community for inspiration and contributions
Support
Deployment
By default this is a stdio MCP server: it is normally launched by an MCP
client (e.g. Claude Desktop) via npx atproto-mcp and communicates over
stdin/stdout, binding no network port. Alternatively, --transport http serves
the MCP Streamable HTTP transport at http://<host>:<port>/mcp (default
binding 127.0.0.1:3000, loopback only); exposing it beyond loopback (e.g.
--host 0.0.0.0) is the operator's responsibility to secure. stdio remains the
default and the recommended setup for MCP clients.
Built-in safeguards
Error sanitization: in
NODE_ENV=production, internal error details are redacted before being returned to the client.Rate limiting: per-tool invocation rate limiting guards against runaway loops.
SSRF protection: outbound URL/media fetches reject private/internal network destinations and cap response size and time.
Path-traversal protection: local file reads are confined to an allowed base directory (
ATPROTO_MEDIA_DIR, default: working directory).
Running in Docker
The container runs the same stdio server, so attach to it via your MCP client rather than mapping a port:
docker build -t atproto-mcp .
docker run -i --rm \
-e ATPROTO_IDENTIFIER=your.handle.bsky.social \
-e ATPROTO_PASSWORD=your-app-password \
atproto-mcpEnvironment configuration
# Copy the example environment file and edit it (loaded automatically by the CLI)
cp .env.example .envATPROTO_IDENTIFIER=your.handle.bsky.social
ATPROTO_PASSWORD=your-app-password
NODE_ENV=production
LOG_LEVEL=infoSee .env.example for the full list of variables the server reads.
Security
Security is a top priority for this project. Please review our security practices and policies:
Security Best Practices
Before deploying to production:
Secure Your Credentials
Never commit
.envfiles to version controlUse app passwords instead of your main account password
Rotate credentials regularly
Use a secret management system where available (AWS Secrets Manager, HashiCorp Vault, etc.)
Run in production mode
Set
NODE_ENV=productionso returned error messages are sanitized
Keep Dependencies Updated
pnpm audit pnpm update
Reporting Security Vulnerabilities
If you discover a security vulnerability, please review our Security Policy for responsible disclosure guidelines.
Do not open public issues for security vulnerabilities. Instead, send me a message privately.
Security Features
Input validation and sanitization
Rate limiting and abuse prevention
Credential redaction in logs
Non-root Docker containers
HTTPS support for AT Protocol
Error sanitization to prevent information leakage
For more details, see SECURITY.md.
Made with ❤️ by Cameron Rye
Available Tools
51 toolsadd_bookmarkAIdempotent
Privately bookmark a post on AT Protocol (app.bsky.bookmark.createBookmark). Bookmarks are private to your account and stored server-side — they are not public records, other users cannot see them, and no bookmark-record URI exists (bookmarks are keyed by the post URI). Only posts can be bookmarked; bookmarking an already-bookmarked post is a no-op. Requires authentication (app password). Use remove_bookmark to remove and get_bookmarks to list. Subject to per-tool rate limiting.
Inputs: uri (required), cid. Returns: success, message, alreadyBookmarked, bookmarkedPost
add_to_listA
Add a user to an existing list. Requires authentication (app password). Creates a listitem record in the authenticated user's repository; the actor's handle is resolved to a DID before insertion. Use remove_from_list to undo the addition and get_list to verify membership. Subject to per-tool rate limiting.
Inputs: listUri (required), actor (required). Returns: success, message, listItem
analyze_accountARead-only
Analyze a single account along one dimension. Requires authentication (app password). Read-only: performs no writes. One account-analysis tool: pick a dimension. For topic/search-based influencer discovery use find_influential_users instead. Subject to per-tool rate limiting.
Inputs: dimension (required), actor, limit, maxSampleSize, +6 more. Returns: Account analysis result; the shape depends on `dimension`. 'engagement' returns…
analyze_imageARead-only
Analyze an image blob's metadata (MIME type, file size in bytes/KB/MB, derived format, and whether it is within optimized-size thresholds) and optionally return human-readable optimization and accessibility suggestions. Does not decode the image, so it cannot report pixel dimensions or aspect ratio. No authentication required. Use upload_image to obtain the blob reference first, then pass it here; prefer this tool over upload_image for pre-flight size checks before actually posting. Subject to per-tool rate limiting.
Inputs: blob (required), includeOptimizationSuggestions. Returns: success, analysis, suggestions
analyze_moderation_statusARead-only
Analyze moderation status of a post or user. Returns content labels, moderation decisions, and personal moderation state (blocks, mutes). Subject can be a DID (for users) or AT-URI (for posts). Works without authentication; richer with auth. Use this tool to evaluate safety before rendering content; use block_user or mute_user to act on the results. Subject to per-tool rate limiting.
Inputs: subject (required), includeLabels. Returns: success, subject, subjectType, moderation, +1 more
batch_actionAIdempotent
Batch the same action across up to 25 targets in one call. Supported actions: follow (handles/DIDs), like (AT-URIs), repost (AT-URIs). Requires authentication (app password). Performs real writes (follows/likes/reposts) to the network on the caller's behalf. Subject to per-tool rate limiting.
Inputs: action (required), targets (required), continueOnError. Returns: success, action, results, summary
block_userADestructive
Block a user to prevent them from seeing your content and interacting with you. Creates a block record in your repo; the action cannot be undone without calling unblock_user. Requires authentication (app password). Use block_user for mutual visibility restriction; use mute_user for a private, one-sided feed suppression that does not affect the target. Subject to per-tool rate limiting.
Inputs: actor (required). Returns: success, message, blockedUser
create_listA
Create a new list for organizing users (curate list) or moderation purposes (mod list). Requires authentication (app password). Creates a permanent list record in the authenticated user's repository; use add_to_list / remove_from_list to manage its members and get_list to inspect them. Subject to per-tool rate limiting.
Inputs: name (required), description, purpose. Returns: success, message, list
create_postA
Create a new post on AT Protocol (Bluesky). The single rich post-creation tool: supports plain text with auto-detected mentions/links/#hashtags, explicit richtext facets, replies, image embeds, a video embed (from upload_video), an external link card, a quote (record) embed, language tags, reply controls (who can reply, via a threadgate record), and quote controls (quote policy, via a postgate record). Requires authentication (app password). SIDE EFFECT: publishes a public post visible to everyone. Subject to per-tool rate limiting. Use create_thread to publish a multi-post chain in one call, and reply_to_post to reply to an existing post; use this tool for a single standalone post (it can also reply via the reply field).
Inputs: text (required), reply, embed, facets, +4 more. Returns: uri, cid, success, message, +2 more
create_threadA
Create a thread of 2–25 posts in a single operation, automatically chaining each post as a reply to the previous one so readers see them as a continuous conversation. Use this instead of repeated create_post calls when content spans multiple posts; use create_post for a single standalone post or reply_to_post to append to an existing thread. Optional replyControls gate who can reply (a threadgate record on the ROOT post, written after the whole thread is published). Requires authentication (app password). If publishing fails mid-thread, already-published posts are returned with a failedAtPosition indicator so you can delete or resume them. Subject to per-tool rate limiting.
Inputs: posts (required), langs, replyControls. Returns: success, message, thread, rootPost, +4 more
delete_postADestructive
Delete a post on AT Protocol. Permanently removes the post from the authenticated user's repository; this action cannot be undone. Use this instead of create_post/reply_to_post when you need to remove existing content. Requires authentication (app password). Subject to per-tool rate limiting.
Inputs: uri (required). Returns: success, message, deletedPost
discoverARead-only
Surface content from your own home timeline. Requires authentication (app password). Read-only: performs no writes. Two timeline-driven discovery modes. For finding accounts similar to a given user use find_similar_users; for topic-based communities use discover_communities. Subject to per-tool rate limiting.
Inputs: mode (required), limit, timeWindow, includeHashtags, +7 more. Returns: success, mode, timeWindow, trendingHashtags, +5 more
discover_communitiesARead-only
Discover communities and groups of users around specific topics or interests by searching recent posts and clustering authors who interact with each other. Works without authentication; richer with auth. Use this instead of find_similar_users when you want topic-based community clusters rather than accounts structurally similar to a specific user. Subject to per-tool rate limiting.
Inputs: topic (required), maxResults, minCommunitySize, includeMetrics. Returns: success, communities, insights
find_influential_usersARead-only
Find influential users in a topic or network by searching recent posts and ranking their authors. Works without authentication; richer with auth. Read-only — produces no side effects. Use this instead of find_similar_users when you want topic-driven discovery of high-reach accounts rather than a specific user's social graph. Subject to per-tool rate limiting.
Inputs: topic, searchQuery, minFollowers, maxResults, +1 more. Returns: success, query, users, insights
find_similar_usersARead-only
Find users similar to a given user based on shared follow-graph connections (second-degree follows and accounts that follow the base user) and follower/following-ratio similarity. Content-topic similarity is NOT analyzed. Works without authentication; richer with auth. Use this instead of search_actors when you want accounts structurally similar to a known user rather than keyword matches. Subject to per-tool rate limiting.
Inputs: actor (required), maxResults, minFollowerCount, includeMetrics. Returns: success, similarUsers, baseUser, insights
follow_userAIdempotent
Follow a user on AT Protocol. Creates a follow record for the specified account; if the account is already followed the existing follow URI is returned without creating a duplicate. Requires authentication (app password). Use unfollow_user to reverse this action; for bulk relationship changes consider batch_action instead. Subject to per-tool rate limiting.
Inputs: actor (required). Returns: uri, cid, success, message, +1 more
generate_link_previewARead-only
Generate a link preview with title, description, and thumbnail for a given URL. Fetches the target page, extracts Open Graph / meta tags, optionally downloads and uploads the og:image thumbnail as an AT Protocol blob, and returns a preview object ready to attach as an external embed to a create_post or create_thread call. Requires authentication (app password). Use this tool before create_post when you want a rich URL card; use upload_image or upload_video for local media instead. Subject to per-tool rate limiting.
Inputs: url (required). Returns: success, message, preview
get_author_feedARead-only
Retrieve posts by a specific AT Protocol user. Works without authentication; richer with auth. Lists a specific user's posts. Differs from get_timeline (your home feed) and search_posts (query-based search). Subject to per-tool rate limiting.
Inputs: actor (required), limit, cursor, filter. Returns: Paginated list of the author's posts.
get_bookmarksARead-only
List the authenticated account's private bookmarks (app.bsky.bookmark.getBookmarks) with cursor pagination. Each entry carries the full bookmarked post view when the post is still viewable, or an unavailableReason (blocked / not_found) when it is not. Requires authentication (app password). Use add_bookmark / remove_bookmark to manage bookmarks. Subject to per-tool rate limiting.
Inputs: limit, cursor. Returns: success, bookmarks, cursor, hasMore
get_conversation_messagesAIdempotent
Read the messages of a Bluesky direct-message conversation (chat.bsky.convo.getMessages, proxied to the bsky.chat service), newest first with cursor pagination. Read-only by default: the conversation is only marked read (unread count cleared) when markRead is true. Requires authentication with an app password created with "Allow access to your direct messages" enabled. Use list_conversations to find conversation ids and send_direct_message to reply. Subject to per-tool rate limiting.
Inputs: convoId (required), limit, cursor, markRead. Returns: One page of messages from the conversation, newest first.
get_custom_feedARead-only
Get posts from a custom algorithm feed. Works without authentication; richer with auth. Returns feed generator metadata and a paginated list of posts; use the returned cursor to fetch subsequent pages. Use get_timeline for the authenticated user's home feed instead. Subject to per-tool rate limiting.
Inputs: feedUri (required), limit, cursor. Returns: success, feed, posts, cursor
get_listARead-only
Get the contents of a list, including all users in the list. Works without authentication; richer with auth. Returns list metadata plus a paginated array of member profiles; use the returned cursor to fetch subsequent pages. Use add_to_list / remove_from_list to modify membership. Subject to per-tool rate limiting.
Inputs: listUri (required), limit, cursor. Returns: success, list, items, cursor
get_notificationsARead-only
Retrieve notifications from AT Protocol (likes, reposts, follows, mentions, replies). Requires authentication (app password). Use countOnly: true to fetch only the unread badge count cheaply without loading the full list; use mark_notifications_seen to clear the unread state after processing. Subject to per-tool rate limiting.
Inputs: limit, cursor, seenAt, countOnly. Returns: Notification result. When countOnly is true only unreadCount is present; otherw…
get_post_contextARead-only
Get comprehensive post information in a single call. Single post reader: use include* flags for thread, author, engagement, and media. Replaces the former get_thread and extract_media_from_post tools. Works without authentication; richer with auth. Subject to per-tool rate limiting.
Inputs: uri (required), includeThread, includeAuthorProfile, includeEngagement, +3 more. Returns: success, post, thread, authorProfile, +2 more
get_starter_packARead-only
Fetch a Bluesky starter pack (app.bsky.graph.getStarterPack) by AT-URI or bsky.app link, returning its name, description, creator, reference-list info, a sample of member profiles, included feeds, and joined counts. Works without authentication. Use search_starter_packs to discover packs by keyword, and get_list to page through the full member list. Subject to per-tool rate limiting.
Inputs: starterPack (required). Returns: success, starterPack
get_timelineARead-only
Retrieve the user's home timeline from AT Protocol, returning posts from followed accounts and algorithmically recommended content. Requires authentication (app password). Use get_author_feed to retrieve posts from a specific user instead of the authenticated user's own feed. Subject to per-tool rate limiting.
Inputs: algorithm, limit, cursor. Returns: success, posts, cursor, hasMore, +1 more
get_user_connectionsARead-only
Retrieve an account's followers or follows from AT Protocol. Works without authentication; richer with auth. Use direction='followers' to get who follows the actor or direction='follows' to get who the actor follows; use get_user_profile or get_user_summary for aggregate counts instead. Subject to per-tool rate limiting.
Inputs: actor (required), direction (required), limit, cursor. Returns: Paginated list of connected accounts.
get_user_profileARead-only
Retrieve a user profile from AT Protocol, returning handle, display name, bio, avatar, banner, follower/following/post counts, and applied labels. Works without authentication; richer with auth — authenticated calls also return viewer-specific fields (following, followedBy, muted, blocking, blockedBy). Use get_user_summary for a condensed overview or get_user_connections for follower/following lists. Subject to per-tool rate limiting.
Inputs: actor (required). Returns: success, profile
get_user_summaryARead-only
Get comprehensive user information in a single call, combining profile, recent posts, and engagement statistics. Works without authentication; richer with auth. Use get_user_profile for just the profile or get_author_feed for posts alone; use this tool when you need both in one round-trip. Subject to per-tool rate limiting.
Inputs: actor (required), includeRecentPosts, postLimit, includeEngagementStats. Returns: success, profile, recentPosts, engagementStats, +1 more
like_postAIdempotent
Like a post on AT Protocol by creating a like record that references the target post. If the post is already liked the existing like is returned without creating a duplicate. Requires authentication (app password). Use unlike_post to remove a like. Subject to per-tool rate limiting.
Inputs: uri (required), cid (required). Returns: uri, cid, success, message, +2 more
list_conversationsARead-only
List the authenticated user's Bluesky direct-message conversations (chat.bsky.convo.listConvos, proxied to the bsky.chat service). Returns each conversation's id, members, unread count, mute state, status (request/accepted) and a last-message preview, plus a pagination cursor. Requires authentication with an app password created with "Allow access to your direct messages" enabled. Use get_conversation_messages to read a conversation and send_direct_message to reply. Subject to per-tool rate limiting.
Inputs: limit, cursor, status. Returns: Paginated list of the user's direct-message conversations.
mark_notifications_seenA
Mark notifications as seen up to a timestamp (defaults to now) so they are not reprocessed on subsequent get_notifications calls. Requires authentication (app password). Persists the seen cursor server-side; use get_notifications to retrieve new notifications after calling this. Subject to per-tool rate limiting.
Inputs: seenAt. Returns: Result of marking notifications as seen.
mute_userAIdempotent
Mute a user to hide their content from your feeds and notifications without them knowing. The muted account is not notified. Requires authentication (app password). Use mute_user for a soft, private suppression; use block_user when you need to prevent the target from seeing your content or interacting with you. Subject to per-tool rate limiting.
Inputs: actor (required). Returns: success, message, mutedUser
remove_bookmarkADestructiveIdempotent
Remove a private bookmark from a post on AT Protocol (app.bsky.bookmark.deleteBookmark). Takes the bookmarked post AT-URI — bookmarks are keyed by post URI, there is no separate bookmark-record URI. Removing a bookmark that does not exist succeeds as a no-op. Requires authentication (app password). Use add_bookmark to add and get_bookmarks to list. Subject to per-tool rate limiting.
Inputs: uri (required). Returns: success, message, wasBookmarked, removedBookmark
remove_from_listADestructiveIdempotent
Remove a user from an existing list. Requires authentication (app password). Deletes the listitem record from the authenticated user's repository; the actor's handle is resolved to a DID and the full list is paged through to locate the record. Use add_to_list to re-add a member or get_list to inspect current members. Subject to per-tool rate limiting.
Inputs: listUri (required), actor (required). Returns: success, message, removedFrom
reply_to_postA
Reply to an existing post on AT Protocol, creating a threaded reply with proper parent and root CID references. Requires authentication (app password). Creates a new post record linked into the thread; the action cannot be undone (use delete_post to remove it afterwards). Use this instead of create_post whenever the new content belongs inside an existing thread; use create_thread to start a multi-post thread from scratch. Subject to per-tool rate limiting.
Inputs: text (required), root (required), parent (required), langs. Returns: uri, cid, success, message, +1 more
report_contentADestructive
Report content that violates community guidelines or terms of service. Submits a moderation report to the network; moderators review it asynchronously and the report cannot be withdrawn once submitted. Requires authentication (app password). Use report_content when you have the AT-URI and CID of the specific post or record; use report_user when reporting an entire account rather than a single piece of content. Subject to per-tool rate limiting.
Inputs: subject (required), reasonType (required), reason. Returns: success, message, reportId, reportDetails
report_userADestructive
Report a user account that violates community guidelines or terms of service. Submits a moderation report targeting the entire account; moderators review it asynchronously and the report cannot be withdrawn once submitted. Requires authentication (app password). Use report_user to flag an account; use report_content when the violation is limited to a specific post or record identified by AT-URI and CID. Subject to per-tool rate limiting.
Inputs: actor (required), reasonType (required), reason. Returns: success, message, reportId, reportDetails
repostA
Repost content on AT Protocol. Reposts the identified post to the authenticated user's feed; if optional quote text is supplied, creates a quote post (new post embedding the original) instead. Requires authentication (app password). Deduplicates plain reposts so retrying on timeout is safe; use unrepost to remove a plain repost. Subject to per-tool rate limiting.
Inputs: uri (required), cid (required), text. Returns: uri, cid, success, message, +3 more
search_actorsARead-only
Search for AT Protocol accounts by handle or display name. Works without authentication; richer with auth. Use this when you know a name but not the exact handle/DID; use get_user_profile when you already have the handle/DID. Subject to per-tool rate limiting.
Inputs: query (required), limit, cursor. Returns: Paginated list of matching accounts.
search_postsARead-only
Search for posts on Bluesky using full-text queries with optional filters for author, language, date range, mentions, domain, and URL. Returns a paginated list of matching posts sorted by recency or engagement. Requires authentication (app password). Use search_actors to find users instead of posts. Subject to per-tool rate limiting.
Inputs: q (required), limit, cursor, sort, +7 more. Returns: success, posts, cursor, hasMore, +2 more
search_starter_packsARead-only
Search for Bluesky starter packs by keyword (app.bsky.graph.searchStarterPacks). Returns a paginated list of matching packs with name, description, creator, member count, and joined counts. Works without authentication. Use get_starter_pack to fetch full details (member sample, feeds, list info) for a specific pack. Subject to per-tool rate limiting.
Inputs: q (required), limit, cursor. Returns: success, query, starterPacks, cursor, +1 more
send_direct_messageA
Send a plain-text Bluesky direct message (chat.bsky.convo.sendMessage, proxied to the bsky.chat service). Target either an existing conversation by convoId, or a recipient by handle/DID via member — the conversation is then resolved (or created) automatically with chat.bsky.convo.getConvoForMembers. Message text is limited to 1000 graphemes / 10000 UTF-8 bytes and is sent without facets (mentions/links appear as plain text). Requires authentication with an app password created with "Allow access to your direct messages" enabled; the recipient's settings must also allow DMs from you. Subject to per-tool rate limiting.
Inputs: text (required), convoId, member. Returns: success, message, convoId, recipientDid, +1 more
unblock_userADestructiveIdempotent
Unblock a previously blocked user to restore normal interactions. Deletes the block record from your repo; if the user was not blocked, the operation returns success=false without error. Requires authentication (app password). Use this instead of unmute_user when the account was restricted via block rather than mute. Subject to per-tool rate limiting.
Inputs: actor (required). Returns: success, message, unblockedUser
unfollow_userADestructive
Unfollow a user on AT Protocol. Deletes the follow record identified by its AT-URI, permanently removing the follow relationship; this action cannot be undone (a new follow_user call is required to re-follow). Requires authentication (app password). Use follow_user to obtain the follow URI before calling this tool; for bulk unfollows consider batch_action. Subject to per-tool rate limiting.
Inputs: followUri (required). Returns: success, message, deletedFollow
unlike_postADestructive
Remove a like from a post on AT Protocol by deleting the like record identified by its AT-URI. This action permanently removes the like and cannot be undone. Requires authentication (app password). Use like_post to add a like. Subject to per-tool rate limiting.
Inputs: likeUri (required). Returns: success, message, deletedLike
unmute_userADestructiveIdempotent
Unmute a previously muted user to restore their content in your feeds. Reverses an earlier mute_user action without notifying the target. Requires authentication (app password). Use this instead of unblock_user when the account was suppressed via mute rather than block. Subject to per-tool rate limiting.
Inputs: actor (required). Returns: success, message, unmutedUser
unrepostADestructive
Remove a repost on AT Protocol. Deletes the repost record owned by the authenticated user, undoing a previous plain repost; this action cannot be undone without re-calling repost. Requires authentication (app password). Use repost to create a repost and this tool only to remove one. Subject to per-tool rate limiting.
Inputs: repostUri (required). Returns: success, message, deletedRepost
update_profileADestructiveIdempotent
Update user profile on AT Protocol. Modifies the display name, description, avatar, and/or banner of the authenticated account; unspecified fields are preserved from the existing profile. Use upload_image to prepare blob values for avatar or banner before calling this tool. Requires authentication (app password). Subject to per-tool rate limiting.
Inputs: displayName, description, avatar, banner. Returns: success, message, updatedFields, profile
upload_imageA
Upload an image file to AT Protocol for use in posts and profiles. Reads a local image file (JPEG, PNG, GIF, WebP, or AVIF; max 1 MB) and uploads it as an AT Protocol blob, returning a blob descriptor and alt text. Pass the returned image.blob object verbatim as embed.images[].image in create_post, as avatar/banner in update_profile, or to analyze_image. Requires authentication (app password). Use upload_video instead for video files. Subject to per-tool rate limiting.
Inputs: filePath (required), altText. Returns: success, message, image
upload_videoA
Upload a video to Bluesky through the app.bsky.video service (video.bsky.app), which transcodes it for playback and stores the processed blob on your PDS. Reads a local video file (MP4, MOV, or WebM; max 100 MB), checks your account video-upload quota, uploads with a service-auth token, polls processing until it completes, and returns the PROCESSED video blob descriptor — pass the returned video.blob object verbatim as embed.video.video in create_post, and any video.captions[].file descriptors as embed.video.captions[].file. WebVTT caption tracks are uploaded as ordinary PDS blobs; caption files the embed lexicon does not support (over 20 kB) are skipped. Requires authentication (app password). Use upload_image instead for still images. Subject to per-tool rate limiting and the video service daily quota.
Inputs: filePath (required), altText, captions. Returns: success, message, video
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 51 tools
Every tool has a clearly distinct purpose, targeting specific actions on specific resources (posts, users, lists, bookmarks, etc.). Overlap is minimal and explicitly addressed in tool descriptions, with cross-references to alternative tools.
Tool names follow a consistent verb_noun pattern (e.g., create_post, delete_post, follow_user, search_actors). The naming convention is uniform across all 51 tools, with no mixing of styles.
51 tools is a high count, but it covers the extensive AT Protocol surface area (posts, threads, likes, reposts, follows, lists, moderation, search, DMs, bookmarks, media uploads). While slightly heavy, each tool serves a necessary function.
The tool surface is remarkably comprehensive, covering virtually all core social media operations including CRUD for posts, follows, likes, reposts, lists, moderation, direct messages, bookmarks, and media. No significant gaps are apparent for the domain.
Maintenance
Related MCP Connectors
Read public AT Protocol profiles, records, threads, backlinks and lexicons. No API key required.
Publish and schedule Bluesky posts and threads from your AI assistant.
Search Bluesky posts and feeds; read profiles, threads, and trends. STDIO or Streamable HTTP.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceMCP server for Bluesky/AT Protocol enabling LLM clients and agents to authenticate, search, post, like, follow, and manage chat on Bluesky.7 npmMIT
- AlicenseBqualityDmaintenanceA Model Context Protocol server that connects to Bluesky and provides natural language tools to interact with the ATProtocol, enabling feed fetching, post management, search, and profile analysis.32MIT
- AlicenseAqualityCmaintenanceEnables search, reading, and posting to Bluesky from any MCP client; features 11 tools (5 read, 6 write) with gated writes requiring explicit confirmation to prevent accidental publishing.117 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables interaction with Bluesky social network through the AT Protocol, including searching posts, fetching profiles, browsing feeds, and retrieving threads and follower data.90 npmMIT