A Bluesky MCP server for the 2026-07-28 era, built on marianoguerra/mcp-server and marianoguerra/atproto. Reads the public AT Protocol AppView with no account and no token; posts with an app password.
Dependencies
moon install marianoguerra/mcp-bsky$ bsky-mcp # stdio, public AppView, anonymous reads
$ bsky-mcp --auth app-password \ # a real account: reads and writes
--identifier alice.bsky.social --app-password xxxx-xxxx-xxxx-xxxx
$ bsky-mcp --service https://my.pds.example # a self-hosted PDS
$ bsky-mcp --http 127.0.0.1:3400 # streamable HTTP instead of stdio| mcp-slack | mcp-bsky | |
|---|---|---|
| Needs an account | no | no |
| Needs a network | no | yes |
| Data is real | no (synthetic) | yes |
| Deterministic | yes | no |
| Writes demoable without consequences | yes | no — a post is public |
| Tool | Backing call | |
|---|---|---|
| R | bsky_whoami | com.atproto.server.getSession |
| R | bsky_get_profile | app.bsky.actor.getProfiles |
| R | bsky_search_actors | app.bsky.actor.searchActors + rank |
| R | bsky_permalink | (pure — no request at all) |
| R | bsky_get_timeline | app.bsky.feed.getTimeline (needs an account) |
| R | bsky_get_author_feed | app.bsky.feed.getAuthorFeed |
| R | bsky_search_posts | app.bsky.feed.searchPosts (needs an account) |
| R | bsky_get_post_thread | app.bsky.feed.getPostThread |
$ just bsky-cli --method tools/list --format json \
| jq -r '.result.tools[] | "\(.annotations.readOnlyHint // false | if . then "R" else "W" end) \(.name)"'
R bsky_whoami
R bsky_get_profile
…
$ just bsky-cli --method tools/call --tool-name bsky_whoami
Not signed in. This server is reading the public Bluesky AppView at public.api.bsky.app
(anonymous), so every read works and every write will refuse.
$ just bsky-cli --method tools/call --tool-name bsky_get_profile --tool-arg actor=bsky.app
Bluesky @bsky.app (did:plc:z72i7hdynmk6r22z27h6tvur) — official Bluesky account …
34477142 followers · 11 following · 806 posts
https://bsky.app/profile/bsky.app$ just bsky-cli --method tools/call --tool-name bsky_get_profile --tool-arg actor='not a handle!'
'not a handle!' is not an account this server can use. Expected a handle, a `did:…` or a
profile URL — Disallowed characters in handle (ASCII letters, digits, dashes, periods only)
isError: truesrc/tools/ the tools, resolution and rendering — native, js, wasm, wasm-gc
src/ the binary — nativeA Bluesky MCP server for the 2026-07-28 era, built on marianoguerra/mcp-server and marianoguerra/atproto. Reads the public AT Protocol AppView with no account and no token; posts with an app password.
Dependencies