Skip to content

io.github.cyanheads/bluesky-mcp-server

by cyanheads · remote · local (npm) · no sign-in to list tools · v0.5.2 · published by GitHub user cyanheads

Search posts, profiles, feeds, threads, and trending topics on Bluesky.

Read only

8 tools: 8 only read.

Scanned Oct 21, 2026

1 check matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http bluesky https://bluesky.caseyjhand.com/mcp

Findings

Matches of fixed checks, with the text they matched.

1 info
  • The description is 2,430 characters long, over the 2,000 this check looks for.

    Matched text

    description ends: "...s from ("### ↳2"), and every post also names its own parent on a "Reply to" line."

    What this check looks for

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

8 tools

Only reads 8Claude Code: allow
  • bsky_get_author_feedGet a Bluesky user's recent feed ordered newest-first.No findings

    Why it is in this group

    • The name "bsky_get_author_feed" says "get": a word for reading.
    Description, as the server wrote it
    Get a Bluesky user's recent feed ordered newest-first. Filter by post type: "posts_with_replies" (everything), "posts_no_replies" (excludes replies), "posts_and_author_threads" (posts the author started), "posts_with_media" (the actor's own posts with images or video — no link cards), or "posts_with_video" (the actor's own video posts). The first three include reposts, so items authored by other accounts appear alongside the actor's own writing — a "repostedBy" field marks those, and the "author" field always names who actually wrote the post; the two media filters return no reposts. Set include_pins to also get the post pinned to the profile, marked "pinned", first on the first page — in addition to "limit", and whether or not it matches the filter. Returns posts with full text, engagement counts, embeds, and AT-URIs for drilling into threads via bsky_get_post_thread. Because "limit" counts reposts too, a page from an account that reposts heavily holds far fewer of that account's own posts than the limit suggests; the enrichment fields report the split, so read "originalPosts" rather than the limit when you want the actor's own writing. Supports cursor pagination.

    Annotations the server declares

    • readOnlyHint: true
    • idempotentHint: true
    • openWorldHint: true
  • bsky_get_feedRead the posts a Bluesky feed generator serves, in the order the feed ranks them.No findings

    Why it is in this group

    • The name "bsky_get_feed" says "get": a word for reading.
    Description, as the server wrote it
    Read the posts a Bluesky feed generator serves, in the order the feed ranks them. Accepts the feed's AT-URI (at://<handle-or-did>/app.bsky.feed.generator/<rkey>) or its bsky.app page (https://bsky.app/profile/<handle-or-did>/feed/<rkey>). Feeds come from the "feedUri" of each bsky_get_trending topic — the way to read what a trend is about — from a quoted feed in a post (an embed with recordKind "generator"), or from a shared link; Discover is at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot. Returns posts with full text, engagement counts, embeds, and AT-URIs for drilling into threads via bsky_get_post_thread. A post the feed pinned to its top carries "pinned: true"; a repost carries "repostedBy". Personalized feeds, which Bluesky serves only to a signed-in account, cannot be read here. Supports cursor pagination.

    Annotations the server declares

    • readOnlyHint: true
    • idempotentHint: true
    • openWorldHint: true
  • bsky_get_followsFetch the social graph edges for a Bluesky account — who follows them, or who they follow.No findings

    Why it is in this group

    • The name "bsky_get_follows" says "get": a word for reading.
    Description, as the server wrote it
    Fetch the social graph edges for a Bluesky account — who follows them, or who they follow. Returns paginated actor profiles (handle, DID, displayName, bio, pronouns when set, and Bluesky verification status) plus a summary of the subject account. Follower, following, and post counts and the website are not on this view, for the listed accounts or the subject — bsky_get_profile returns them for one account. Accounts with large social graphs return only the first page; use cursor pagination to walk through the full list, or sort "top" to put the accounts Bluesky ranks most prominent first.

    Annotations the server declares

    • readOnlyHint: true
    • idempotentHint: true
    • openWorldHint: true
  • bsky_get_post_quotesRead the quote posts behind a Bluesky post's "quoteCount" — the posts that embed it with commentary of their own, newest first.No findings

    Why it is in this group

    • The name "bsky_get_post_quotes" says "get": a word for reading.
    Description, as the server wrote it
    Read the quote posts behind a Bluesky post's "quoteCount" — the posts that embed it with commentary of their own, newest first. On Bluesky this is where much of the reaction to a post lives; bsky_get_post_thread returns replies only. Accepts the post's AT-URI (at://<handle-or-did>/app.bsky.feed.post/<rkey>) from the "uri" field of any returned post, or its bsky.app URL (https://bsky.app/profile/<handle-or-did>/post/<rkey>); a handle costs one extra lookup. Returns each quote post with full text, author, engagement counts, and AT-URI. Each result's embed names the queried post by AT-URI and CID only — its text is not repeated on every result — and keeps any media the quoting post attached. "quoteCount" is an upper bound on what this returns: Bluesky's counter keeps quotes that have left the index. Supports cursor pagination.

    Annotations the server declares

    • readOnlyHint: true
    • idempotentHint: true
    • openWorldHint: true
  • bsky_get_post_threadFetch the conversation for a post by AT-URI — the parent chain upward and the reply tree downward.1 finding

    Why it is in this group

    • The name "bsky_get_post_thread" says "get": a word for reading.

    Findings

    • Info

      The description is 2,430 characters long, over the 2,000 this check looks for.

      Matched text

      description ends: "...s from ("### ↳2"), and every post also names its own parent on a "Reply to" line."

      What this check looks for
    Description, as the server wrote it
    Fetch the conversation for a post by AT-URI — the parent chain upward and the reply tree downward. Enter the thread at any point and traverse the discussion. AT-URIs have the format "at://<handle-or-did>/<collection>/<rkey>" and are returned in the "uri" field of every post the other post-returning tools emit, such as bsky_get_feed and bsky_get_author_feed; a bsky.app post URL (https://bsky.app/profile/<handle-or-did>/post/<rkey>) works as-is. Returns the root post, parent chain, and nested replies with per-post author and engagement data. Replies only: quote posts are not part of a thread — read them with bsky_get_post_quotes. The response is often a fraction of the conversation: Bluesky holds replies back past a per-post limit and offers no way to page the rest, so a thread with thousands of replies commonly returns a few hundred. Any node returning fewer replies than its own replyCount carries "truncated: true" with "unreturnedReplies" and a "truncationReason" — "depth" means the reply tree ended there and fetching that node's AT-URI as its own thread continues below it, "unavailable" means no request closes the gap. Read "unreturnedReplies" as an upper bound on what is missing rather than a count of readable replies: Bluesky's counter also includes replies that have left the index, so a small difference often means nothing is left to fetch. The parent chain is disclosed the same way: when it stops at parent_height instead of at the start of the conversation, the topmost node carries "parentChainTruncated: true" and fetching its AT-URI as its own thread continues upward. The enrichment fields total the difference for the whole thread; check them before describing a conversation as complete or naming its first post. A thread that would pass this server's 48,000-byte response budget is cut between whole posts — the target kept first, then its parents nearest-first, then replies level by level — with "budgetCapped: true" and the cut marked where it happened: "budgetOmittedReplyUris" on the target and "budgetOmittedReplies" on a kept reply name the replies left out, "budgetOmittedParents" on the topmost parent the ancestors; fetching those AT-URIs as their own threads reads the rest. In the rendered text nothing is indented: a reply's author heading carries how far it sits below the top-level reply it descends from ("### ↳2"), and every post also names its own parent on a "Reply to" line.

    Annotations the server declares

    • readOnlyHint: true
    • idempotentHint: true
    • openWorldHint: true
  • bsky_get_profileFetch a Bluesky actor's public profile by handle (e.g.No findings

    Why it is in this group

    • The name "bsky_get_profile" says "get": a word for reading.
    Description, as the server wrote it
    Fetch a Bluesky actor's public profile by handle (e.g. "bsky.app") or DID (e.g. "did:plc:z72i7hdynmk6r22z27h6tvur"). Returns displayName, handle, DID, bio, pronouns, website, follower/following/post counts, avatar URL, moderation labels, pinned post AT-URI, and Bluesky verification — whether the account is verified or a trusted verifier, and who verified it. Use this as the first step to resolve a handle to a DID before calling tools that require a DID or AT-URI. Handles and DIDs are interchangeable as input, and "@bsky.app" or the account's bsky.app page (https://bsky.app/profile/bsky.app) work as-is.

    Annotations the server declares

    • readOnlyHint: true
    • idempotentHint: true
    • openWorldHint: true
  • bsky_search_actorsFind Bluesky accounts by name or handle fragment.No findings

    Why it is in this group

    • The name "bsky_search_actors" says "search": a word for reading.
    Description, as the server wrote it
    Find Bluesky accounts by name or handle fragment. Returns ranked profiles with handle, DID, displayName, bio, pronouns when the account set them, and Bluesky verification status — which tells a verified account from a look-alike handle. Follower, following, and post counts and the website are not on this view — bsky_get_profile returns them for one account. Use before bsky_get_profile or bsky_get_author_feed when you have a name but not a confirmed handle. Supports cursor-based pagination for browsing beyond the first page of results.

    Annotations the server declares

    • readOnlyHint: true
    • idempotentHint: true
    • openWorldHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Install

Pinned to version 0.5.2. Values in angle brackets are yours to fill in.

claude mcp add --transport http bluesky https://bluesky.caseyjhand.com/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__bluesky__bsky_get_profile",
      "mcp__bluesky__bsky_search_actors",
      "mcp__bluesky__bsky_get_trending",
      "mcp__bluesky__bsky_get_feed",
      "mcp__bluesky__bsky_get_author_feed",
      "mcp__bluesky__bsky_get_post_thread",
      "mcp__bluesky__bsky_get_post_quotes",
      "mcp__bluesky__bsky_get_follows"
    ],
    "ask": [],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as bluesky. Review it before you use it.