Bluesky MCP Server & CLI
A free, open source Bluesky MCP server and CLI that lets Claude Code, Codex, Cursor and other AI agents post, read, search and manage your Bluesky account.
This free Bluesky MCP server and CLI gives your AI real access to your Bluesky account. It can post, read your timeline, search, follow and check what worked.
It's one install with 2 ways in. Claude, Codex, Cursor or any other MCP app calls its 45 tools for you, and the same tools work as a CLI that agents like Claude Code, Codex and OpenCode run, or that you type yourself.
Here's what the Bluesky MCP server is, how to set it up in each app, and every tool it has.
What is the Bluesky MCP server & CLI?
The Bluesky MCP server & CLI is a free, open source program that lets AI agents act on Bluesky for you, in 2 ways. The MCP server is what an AI app like Claude, Codex or Cursor connects to, through MCP (Model Context Protocol), the open standard AI apps use to call outside tools.
You ask in plain language. Your AI picks the right tool, and the server makes the call to Bluesky.
The CLI is the same program as commands. bluesky-cli get-timeline runs the same code your AI runs when you ask about your timeline, whether an agent like Claude Code runs it or you do.
What can you ask it?
Once it's set up, you ask the way you'd ask a person. These are real prompts it handles:
Try askingPost this, and put the link in a card rather than as bare text.
Turn these notes into a thread. Show me the draft first.
What did my timeline talk about in the last 12 hours?
Read the replies to my Tuesday post and tell me which ones deserve an answer.
Study @someone's last 100 posts and tell me what gets engagement for them, relative to their follower count.
Which of my posts got quoted more than they got reposted?
The last one shows why this is useful. Bluesky counts quotes, reposts and replies separately, and a post quoted more than it's reposted usually means people disagreed.
How to install the Bluesky MCP server
Pick your app in the box at the top of this page. Each one is a single command or a pasted block, and they all run through npx, so there's nothing to install first.
Pro tip: Most reading works with no password at all. Profiles, other people's posts, threads, custom feeds and trends all answer without one.
Set up your Bluesky account
Bluesky has app passwords: separate passwords you make for one program and can revoke at any time. Never give the server your real password.
Your handle needs its domain. alice won't resolve, and alice.bsky.social will.
Or let your AI set it up
Your AI can't make the app password for you, but it can walk you through it and do the rest. Paste this into Claude Code, Codex or any agent that can run commands:
Set up the Bluesky MCP serverSet up the Bluesky MCP server for me.
1. Tell me to open https://bsky.app/settings/app-passwords, sign in, click Add App Password, name it "mcp", and paste the xxxx-xxxx-xxxx-xxxx value back to you. You cannot do this part yourself, so stop and wait for it.
2. Ask me for my full Bluesky handle, including the domain, e.g. me.bsky.social.
3. Register the server with my MCP client, passing BLUESKY_IDENTIFIER and BLUESKY_APP_PASSWORD as environment variables. For Claude Code that is:
claude mcp add bluesky -e BLUESKY_IDENTIFIER=<handle> -e BLUESKY_APP_PASSWORD=<password> -- npx -y @thenavidm/bluesky-mcp-cli
For any other client, write the equivalent JSON into its MCP config file.
4. Run `npx -y @thenavidm/bluesky-mcp-cli doctor` and show me the output.
5. If every line says ok, tell me to restart the client. If any line says FAIL, tell me what it says and what to do about it. Do not try to guess my password or handle, and do not post anything.
It stops at step 1 and waits, because only you can create the app password.
Check that it works
Run the doctor. It checks the network, then your account, then a real read and a real write, and names the fix for anything that fails.
npx -y @thenavidm/bluesky-mcp-cli doctorWhen every line says ok, restart your app and ask it who you are on Bluesky. A FAIL on the write check usually means the app password was mistyped.
Use the Bluesky CLI
The CLI is the same 45 tools as commands. AI agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal or a script. Every tool name becomes a command with dashes, so create_post runs as bluesky-cli create-post.
npm install -g @thenavidm/bluesky-mcp-cli
bluesky-cli
bluesky-cli get-author-feed --actor navid.me
bluesky-cli search-posts "model context protocol"
bluesky-cli create-post --text "Shipped." --confirmThe bare bluesky-cli lists every command, and bluesky-cli <command> --help shows what a command takes. Posting, deleting and blocking need --confirm, the terminal's version of the check your AI has to pass.
These flags work on every command:
| Flag | What it does |
|---|---|
--json | Prints JSON |
--compact | Prints the JSON on one line |
--agent | Machine mode: JSON, compact, no prompts and no color |
--select a,b.c | Keeps only those fields, and a dotted path goes deeper |
--confirm | Lets a write that asks first go ahead |
A script can branch on the exit code:
| Exit code | What it means |
|---|---|
| 0 | It worked |
| 2 | The command was typed wrong, or a write needed --confirm |
| 3 | It wasn't found |
| 4 | Bluesky rejected the credentials |
| 5 | Bluesky's API failed |
| 7 | You hit a rate limit, so wait and try again |
| 10 | Nothing is set up yet |
MCP server or CLI: which one?
Both are the same program with the same 45 tools. The difference is when your AI pays for them, in the tokens it reads.
- MCP server
- 15,900 tokens
- CLI
- Nothing
- MCP server
- 1,100 tokens
- CLI
- Nothing
- MCP server
- Nothing more, or in Claude Code the tools it picks
- CLI
- 1,900 tokens, once
- MCP server
- 317,000 tokens
- CLI
- 1,900 tokens
- MCP server
- Yes
- CLI
- No, there's no terminal there
- MCP server
- No
- CLI
- Yes
An app that loads every tool up front sends the full list with every message, whether you mention Bluesky or not. Claude Code doesn't by default: its tool search sends only the tool names and the server's instructions, and loads a tool's full definition when your AI reaches for it.
The CLI costs nothing until Bluesky comes up. Then your agent reads its skill file once and runs the commands it needs. With the skill added, Claude Code also lists its one-line description with every message, about 150 tokens.
When the whole conversation is about Bluesky, the gap closes. Then the MCP server is the better experience, because you ask in plain language and your AI never has to look up a command.
Where the MCP server's tokens go
| Part of the tool list | Share |
|---|---|
| JSON Schema structure, like types, required lists and nesting | 55% |
| Argument descriptions | 31% |
| Tool descriptions | 14% |
55% of it is MCP writing every tool out as JSON Schema, which any server with this many tools pays. The rest is the wording that lets your AI use each tool without guessing.
How to spend less
In Claude Code, leave tool search on, which it is unless you've set ENABLE_TOOL_SEARCH=false.
Turn the server off when you aren't using Bluesky. In Claude Code that's the /mcp panel, and every AI app has its own switch. BLUESKY_READ_ONLY=1 cuts it to the 30 reading tools.
Or install the CLI and connect the server later, on the days it earns its place. Every tool stays in reach, and the standing cost drops to nothing.
Every number here was measured on September 27, 2026 in Claude Code 2.1.257 with Claude Opus 5. It's the same one-line prompt with and without the server connected, once with tool search off so every tool loads, and once with Claude Code's default. The skill was measured the same way, and other apps and models count tokens a little differently.
Every Bluesky tool
All 45 tools, grouped the way the repo groups them. 30 only read, and 15 change something on your account.
Posting
create_post- What it does
- Publish a post.
- Kind
- Asks first
create_thread- What it does
- Publish several posts as one thread, each replying to the last.
- Kind
- Asks first
delete_post- What it does
- Delete one of your own posts.
- Kind
- Asks first
get_post_thread- What it does
- Read a post together with the conversation around it: everything above it and the replies below.
- Kind
- Reads
Reading posts
get_timeline- What it does
- Your following feed, newest first.
- Kind
- Reads
get_author_feed- What it does
- Posts by one account, newest first.
- Kind
- Reads
get_liked_posts- What it does
- Posts a connected account has liked, newest first.
- Kind
- Reads
get_post_likes- What it does
- The accounts that liked a specific post, newest first.
- Kind
- Reads
get_reposted_by- What it does
- The accounts that reposted a specific post.
- Kind
- Reads
get_quotes- What it does
- Posts that quote a specific post.
- Kind
- Reads
Search and feeds
search_posts- What it does
- Full-text search across public posts.
- Kind
- Reads
search_actors- What it does
- Find Bluesky accounts by name, handle or bio text.
- Kind
- Reads
search_feeds- What it does
- Find custom feeds, meaning the algorithmic feeds anyone on Bluesky can publish.
- Kind
- Reads
get_feed- What it does
- Read posts from a custom feed by its at:// URI or bsky.app link.
- Kind
- Reads
get_pinned_feeds- What it does
- The feeds and lists pinned to a connected account's home screen, in order.
- Kind
- Reads
get_list_posts- What it does
- Posts from the accounts on a curated list, newest first.
- Kind
- Reads
get_trends- What it does
- Current trending topics on Bluesky, each with the feed link that shows the posts behind it.
- Kind
- Reads
get_suggested_follows- What it does
- Accounts Bluesky suggests following.
- Kind
- Reads
Likes, reposts and follows
like_post- What it does
- Like a post.
- Kind
- Writes
unlike_post- What it does
- Remove your like from a post.
- Kind
- Writes
repost- What it does
- Repost a post to your followers.
- Kind
- Writes
unrepost- What it does
- Remove your repost of a post.
- Kind
- Writes
follow- What it does
- Follow an account by handle or DID.
- Kind
- Writes
unfollow- What it does
- Stop following an account.
- Kind
- Writes
mute_account- What it does
- Hide an account's posts from your feeds without them knowing.
- Kind
- Writes
unmute_account- What it does
- Stop hiding an account's posts.
- Kind
- Writes
block_account- What it does
- Block an account.
- Kind
- Asks first
unblock_account- What it does
- Remove a block.
- Kind
- Writes
set_reply_permissions- What it does
- Change who is allowed to reply to one of your existing posts, after it is already published.
- Kind
- Writes
Profiles and lists
get_profile- What it does
- Full profile for one or more accounts: bio, follower counts, labels, and, when a connected account is available, whether you follow them and whether they follow you.
- Kind
- Reads
get_followers- What it does
- Accounts that follow a given account, newest first.
- Kind
- Reads
get_follows- What it does
- Accounts a given account follows.
- Kind
- Reads
get_relationships- What it does
- For each account named, whether a connected account follows them and whether they follow back.
- Kind
- Reads
get_lists- What it does
- Curated lists an account has created.
- Kind
- Reads
get_list_members- What it does
- The accounts on a curated list.
- Kind
- Reads
Notifications
get_notifications- What it does
- Your likes, reposts, follows, mentions, replies and quotes, newest first.
- Kind
- Reads
get_unread_count- What it does
- How many notifications have arrived since you last marked them seen.
- Kind
- Reads
mark_notifications_seen- What it does
- Mark every notification up to now as seen, so the unread count resets.
- Kind
- Writes
Analytics
rank_posts- What it does
- Your posts, best first, with likes, reposts, replies and quotes for each.
- Kind
- Reads
get_post_stats- What it does
- Likes, reposts, replies and quotes for a single post, by URL or at:// URI.
- Kind
- Reads
get_engagement_summary- What it does
- Totals, averages and engagement rate across recent posts, broken down by format so you can see whether images or video actually earn their effort.
- Kind
- Reads
get_posting_patterns- What it does
- Your posting times crossed with the engagement they earned, by hour and by weekday, so 'when should I post' is answered from your own account rather than a generic chart.
- Kind
- Reads
Accounts
list_accounts- What it does
- List every Bluesky account this server can act as.
- Kind
- Reads
whoami- What it does
- Authenticate and return the live profile for a connected account, including follower counts.
- Kind
- Reads
get_video_job_status- What it does
- Check a Bluesky video transcoding job by id.
- Kind
- Reads
Is the Bluesky MCP server safe?
A post is public the moment it lands, and deleting it doesn't pull it out of feeds that already have it. So 4 tools refuse to run until your AI passes confirm: true. They're the ones marked Asks first in the tool tables above.
Likes, reposts, follows and mutes don't ask first, because each is one click to undo. Asking on every like would only train your AI to pass the check without thinking.
Make it read-only
Set BLUESKY_READ_ONLY=1 and every write disappears from the tool list, leaving 30 reading tools. Your AI can't call a tool it can't see.
BLUESKY_ALLOW_DESTRUCTIVE=0 is the middle setting. Likes and follows still work, and posting, deleting and blocking don't.
Keep a log of every write
Set BLUESKY_AUDIT_LOG to a file path. The server writes one line per attempted write, allowed or blocked, with the time and what it was about to do.
Watch out: Everything your AI reads from Bluesky was written by other people, and a post can try to give it orders. The server tells your AI to treat it as data, but BLUESKY_READ_ONLY=1 is the real defense for an agent reading other people's posts.
Your data
Nothing goes anywhere but Bluesky. Your app password stays in your app's config or your shell, session tokens stay in memory and are never written to disk, and there's no tracking of any kind.
To disconnect, delete the app password at bsky.app/settings/app-passwords. That cuts access right away, and nothing else about your account changes.
Connect more than one Bluesky account
A personal handle and a brand handle both work from one server, with no restart to switch. Get an app password for each account, then set them together:
export BLUESKY_ACCOUNTS='[{"handle":"you.bsky.social","app_password":"xxxx-xxxx-xxxx-xxxx"},{"handle":"brand.example.com","app_password":"yyyy-yyyy-yyyy-yyyy"}]'
export BLUESKY_DEFAULT_ACCOUNT=you.bsky.socialEvery tool that acts as you takes an optional account, so you can say which handle posts. Your AI calls list_accounts when it isn't clear which one you mean.
Bluesky MCP server settings
Every setting is an environment variable, in your app's config or your shell.
BLUESKY_IDENTIFIER- Default
- none
- What it does
- Sets your full handle
BLUESKY_APP_PASSWORD- Default
- none
- What it does
- Sets an app password, never your account password
BLUESKY_SERVICE_URL- Default
https://bsky.social- What it does
- Points at your PDS, if you host your own
BLUESKY_ACCOUNTS- Default
- none
- What it does
- Lists several accounts, as JSON
BLUESKY_DEFAULT_ACCOUNT- Default
- the first one
- What it does
- Picks the handle that acts when a tool names none
BLUESKY_READ_ONLY- Default
0- What it does
1hides every write
BLUESKY_ALLOW_DESTRUCTIVE- Default
1- What it does
0blocks posting, deleting and blocking
BLUESKY_AUDIT_LOG- Default
- none
- What it does
- Logs every attempted write to a file
BLUESKY_REQUEST_TIMEOUT_MS- Default
30000- What it does
- Sets how long a request can take
BLUESKY_MAX_RETRIES- Default
3- What it does
- Retries after a rate limit or a server error
Troubleshooting
Run the doctor first. It names the step that failed and the fix.
| What you see | What to do |
|---|---|
| "Bluesky rejected the credentials" | You used your account password. Make an app password instead |
| "No account resolves for …" | Add the domain to your handle: alice.bsky.social, not alice |
search_posts returns 403 | Searching posts needs a signed-in account, so set up an app password |
| "Image is 2.4MB; Bluesky's limit is 1MB" | Make the image smaller and try again |
| "will not run without confirm: true" | That's the safety check working. Say you want it posted |
| Rate limited | Bluesky limits writes per hour and per day, so wait and try again |
If the server doesn't show up in your app at all, run the command your app runs, in a terminal, and read the error.
More free Bluesky tools
Check a post's length before your AI sends it, or turn a post into an image to share.
Bluesky MCP Server FAQs
Here are the questions people ask most about the Bluesky MCP server and CLI.
The Bluesky MCP server & CLI is a free, open source program that lets an AI app like Claude, Codex or Cursor act on your Bluesky account.
It has 45 tools for posting, threads, replies, your timeline, search, custom feeds, lists, notifications and follows, and the same tools run as a CLI that agents like Claude Code and Codex use, or that you type yourself.
An MCP server is a standard way to give an AI app real access to a tool, so it can act instead of guessing.
MCP stands for Model Context Protocol, and Claude, Codex, Cursor and many other AI apps speak it.
The Bluesky CLI is the same program as the Bluesky MCP server, run as commands.
AI agents like Claude Code, Codex and OpenCode run them for you, and you can type them in a terminal or a script.
Every tool is a command with dashes, so create_post runs as bluesky-cli create-post, and one npm package installs both.
Use the Bluesky MCP server in an AI app with no terminal, like Claude Desktop's chat, and the CLI in a terminal, a script or a cron job.
In an AI app that can run commands, like Claude Code, Codex or Cursor, the CLI is the lighter choice, because it costs nothing until it runs.
Yes, the Bluesky MCP server is free and open source under the MIT license.
Bluesky's API is free too, so the only thing you pay for is your own AI app.
No, you don't need a developer account.
Bluesky has no developer portal and no app to register, so your handle and an app password are all the Bluesky MCP server needs.
The Bluesky MCP server uses an app password because you can revoke it on its own, and it can't change your email or your real password.
Never put your account password in the config.
The Bluesky MCP server posts when you ask it to.
Posting, threads, deleting and blocking only run once your AI passes a confirm check, and read-only mode removes every write so your AI can't see them at all.
The Bluesky MCP server works with any app that speaks MCP.
That includes Claude Code, Claude Desktop, Codex, Cursor, VS Code, GitHub Copilot CLI, Gemini CLI, OpenCode, OpenClaw, Antigravity and Hermes, with the same package and the same settings.
Yes, the Bluesky MCP server connects as many accounts as you set up.
Every tool takes an optional account, and a default decides which one acts when you don't say.
To disconnect the Bluesky MCP server, delete its app password in Bluesky's settings, which cuts access right away.
Then remove the server from your AI app's config.
Navid.me is reader-supported. When you buy through links on this site, I may earn an affiliate commission. Learn more.
More MCP servers & CLIs
The most actionable AI newsletter for founders
Every week, get proven AI strategies, curated tools, and step-by-step systems to grow your audience, create better content, and build a profitable creator business.
No fluff, no filler, no BS. Just five minutes each week that might level up your online business and life.
P.S. Sign up now to get free access to my ultimate AI tools guide for creators.


