Bluesky Social Search, Profiles & Post Threads MCP Server
Pricing
Pay per usage
Bluesky Social Search, Profiles & Post Threads MCP Server
Search Bluesky / AT Protocol posts, author feeds, actor profiles, follower ratios, and nested discussion threads via zero-proxy Batch JSON API or Standby MCP Server.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Mutualistic Labs
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
MCP Server for AI Agents: Bluesky Social Search & Threads
An always-on Model Context Protocol (MCP) server and batch Actor for Bluesky (AT Protocol): full-text post search, author feeds, profiles with follower-to-following ratios and complete reply threads with parent context. Built for AI agents (Claude Desktop, Cursor, Windsurf, OpenAI Agents, LangChain), social listening, brand and topic monitoring, influencer research and conversation analysis.
No proxies, no browser, no logins, no cookies: only the public, unauthenticated AT Protocol AppView XRPC API is called
(api.bsky.app, with automatic failover to public.api.bsky.app).
Features
- Four modes:
search_posts,author_feed,profiles,post_thread. - Post search with
sort(latestortop), author,lang,tag, linkeddomain,since/untildate range and engagement filters (min_likes,min_reposts,min_replies). - Author feeds for one or many handles, DIDs or
https://bsky.app/profile/...URLs (up to 10), with the four feed filters. - Profiles with
followers_count,follows_count,posts_count,follower_to_following_ratio, bio, labels and pinned post. - Full threads: parent chain (negative
thread_depth), anchor post (0) and nested replies (1 to 10 levels). - Hashtags, links and mentions extracted from rich-text facets; images and link cards from embeds.
- Resilient search: if
searchPostsis blocked (401/403) on both hosts, the Actor falls back to actor search plus author feeds (source=search_fallback). - Deterministic de-duplication (
uid), hardmax_itemsandmax_total_charge_usdcaps.
What you get
record_type | Mode | What it is |
|---|---|---|
post | search_posts, author_feed, post_thread | One post (text, author, counters, hashtags, links, mentions, embed, reply context) |
profile | profiles | One account (identity, bio, counters, follower ratio, labels, pinned post) |
Endpoints
GET /andGET /health: readiness probe, returns{"status":"ok","actor":"bluesky-social-search-mcp",...}.POST /mcp: MCP JSON-RPC 2.0 (initialize,ping,tools/list,tools/call).
Standby URL: https://mutualistic-housing--bluesky-social-search-mcp.apify.actor/mcp (authenticate with your Apify API token).
Input
| Field | Type | Default |
|---|---|---|
mode | search_posts, author_feed, profiles, post_thread | author_feed |
actors | string[] (handles, DIDs or profile URLs, 1 to 10) | none (prefill bsky.app; author_feed/profiles fall back to bsky.app) |
query | string, max 300 chars (required for search_posts; keyword filter in author_feed; actor search in profiles) | none |
sort | latest or top (mode search_posts) | latest |
feed_filter | posts_with_replies, posts_no_replies, posts_with_media, posts_and_author_threads | posts_no_replies |
post_urls | string[] of post URLs, at:// URIs or handle/rkey pairs (mode post_thread, 1 to 25) | none |
thread_depth | integer 0 to 10 | 3 |
lang | language code such as en | none |
tag | hashtag without #, max 64 chars | none |
domain | linked domain, mode search_posts | none |
since, until | YYYY-MM-DD or ISO 8601 timestamp, mode search_posts | none |
min_likes, min_reposts, min_replies | integer >= 0 (0 means no filter) | none |
max_items | integer 1 to 500 | 25 |
max_total_charge_usd | number or null | no cap |
An empty {} input runs: the 25 latest posts (without replies) of bsky.app. camelCase aliases (postUrls, threadDepth,
feedFilter, minLikes, minReposts, minReplies, maxItems, maxTotalChargeUsd) are accepted. Invalid input is rejected with
INVALID_INPUT_ZERO_CHARGE before any network call or charge.
Batch input examples
Top English posts about a topic with at least 10 likes:
{"mode": "search_posts", "query": "atproto", "sort": "top", "lang": "en", "min_likes": 10, "max_items": 50}
Recent posts of two accounts:
{"mode": "author_feed", "actors": ["jay.bsky.team", "https://bsky.app/profile/pfrazee.com"], "max_items": 40}
Profiles with follower ratios:
{"mode": "profiles", "actors": ["bsky.app", "danabra.mov", "simonwillison.net"]}
Find accounts by keyword:
{"mode": "profiles", "query": "machine learning", "max_items": 20}
Full discussion thread with 5 reply levels:
{"mode": "post_thread", "post_urls": ["https://bsky.app/profile/bsky.app/post/3mykvymup7s2l"], "thread_depth": 5}
MCP tools
{"mcpServers": {"bluesky": {"url": "https://mutualistic-housing--bluesky-social-search-mcp.apify.actor/mcp","headers": { "Authorization": "Bearer <APIFY_TOKEN>" }}}}
search_bluesky_posts:query(required),sort,actors,lang,tag,min_likes,min_reposts,min_replies,max_items(default 10).get_author_feed:actors,feed_filter,query,min_likes,min_reposts,max_items.get_bluesky_profiles:actors,query,max_items.get_post_thread:post_urls(required),thread_depth,max_items.list_preset_accounts: no arguments; lists the preset accounts (free).
Example calls:
curl -X POST "https://mutualistic-housing--bluesky-social-search-mcp.apify.actor/mcp" \-H "Authorization: Bearer <APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_bluesky_posts","arguments":{"query":"atproto","sort":"top","max_items":5}}}'
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_author_feed","arguments":{"actors":["jay.bsky.team"],"max_items":10}}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_bluesky_profiles","arguments":{"actors":["bsky.app","pfrazee.com"]}}}
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"get_post_thread","arguments":{"post_urls":["https://bsky.app/profile/bsky.app/post/3mykvymup7s2l"],"thread_depth":3}}}
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"list_preset_accounts","arguments":{}}}
Output fields
post:
| Field | Meaning |
|---|---|
record_type, uid | post; deterministic SHA-256 identifier |
uri, cid, rkey, post_url | AT URI, content id, record key and public bsky.app URL |
author_did, author_handle, author_display_name, author_avatar | Author identity (avatar is https only) |
text, created_at, indexed_at, langs | Post text, timestamps and declared languages |
tags, urls, mentions | Hashtags, https links and mentioned DIDs from the rich-text facets |
like_count, repost_count, reply_count, quote_count, bookmark_count | Engagement counters (non-negative integers) |
engagement_total | like_count + repost_count + reply_count + quote_count (bookmarks excluded) |
is_reply, reply_root_uri, reply_parent_uri | Reply context |
embed_type, external_url, external_title, images | images, external, record, record_with_media, video or other; link card; full-size image URLs |
thread_depth | Mode post_thread: negative = ancestor, 0 = anchor, positive = reply level; otherwise null |
source | search_posts, author_feed, post_thread or search_fallback |
profile:
| Field | Meaning |
|---|---|
record_type, uid | profile; deterministic SHA-256 identifier |
did, handle, display_name, description | Identity and bio |
avatar, banner, profile_url | Images (https only) and public profile URL |
followers_count, follows_count, posts_count | Counters (non-negative integers) |
follower_to_following_ratio | followers / follows rounded half-up to 2 decimals; null when follows_count is 0 |
created_at, indexed_at | Timestamps |
labels, pinned_post_uri | Label values (moderation and verification) and the pinned post |
source | get_profile or search_actors |
Example post (shortened):
{"record_type": "post", "uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3mykvymup7s2l","post_url": "https://bsky.app/profile/bsky.app/post/3mykvymup7s2l", "author_handle": "bsky.app","text": "Hello from Bluesky #atproto", "created_at": "2026-10-20T12:00:00.000Z", "langs": ["en"], "tags": ["atproto"],"like_count": 3968, "repost_count": 518, "reply_count": 2618, "quote_count": 5939, "bookmark_count": 627,"engagement_total": 13043, "is_reply": false, "embed_type": null, "thread_depth": null, "source": "author_feed", "uid": "<sha256>"}
Preset accounts
Use the handle in actors; any other handle, DID or profile URL works too.
| Handle | Account | Category |
|---|---|---|
bsky.app | Bluesky Official | platform |
jay.bsky.team | Jay Graber | leadership |
pfrazee.com | Paul Frazee | protocol |
danabra.mov | Dan Abramov | engineering |
simonwillison.net | Simon Willison | ai |
karpathy.bsky.social | Andrej Karpathy | ai |
Security and limits
- Allowlisted hosts only: outbound requests go exclusively to
api.bsky.appandpublic.api.bsky.appover https. Redirects to any other host, non-https redirects, credentials in URLs and non-443 ports are rejected. - SSRF protections: IP literals,
localhost,.localand.internalnames are never accepted as actors; DNS results (and the connected peer address, checked before any body is read) that are loopback, private, link-local, CGNAT, NAT64, 6to4, Teredo, multicast or unspecified are refused. Resolved IP addresses never appear in error messages. - Bounds: at most 500 items per run, 10 actors per call, 25 post URLs in mode
post_thread, a 120 s global batch deadline, a 45 s deadline per MCP tool call, a 15 s per-request timeout (connect, TLS, headers and body) and a 2 MiB response size cap. - MCP server: request bodies above 64 KiB return
413,POST /mcprequiresContent-Type: application/json(415otherwise) and at most 8 concurrent tool calls run (503when busy). - Untrusted content: post text, display names and bios are user-generated. Sanitize them before rendering them in a browser or UI.
- Unknown or deleted accounts and posts return an error entry for that actor or post; rate limits (
429) and 5xx responses are retried with back-off, and per-actor failures never abort other actors.
Pricing
Pay per event: $0.001 per result-item (result-item: one de-duplicated post or profile, as a dataset item or an MCP tool result
row); the actor-start event is free and list_preset_accounts is free. max_items and max_total_charge_usd are hard caps
enforced in code, so a run never charges more than you configure. Invalid input and empty results are never charged.