This skill provides access to the Bluesky AT Protocol social network, enabling agents to browse profiles, search content, consume feeds, manage social connections, engage with posts, and handle notifications through public and authenticated API operations.
Resources
7Install
npx skillscat add imoonkey/openweb/src-sites-bluesky Install via the SkillsCat registry.
About this skill
This skill provides access to the Bluesky AT Protocol social network, enabling agents to browse profiles, search content, consume feeds, manage social connections, engage with posts, and handle notifications through public and authenticated API operations.
SKILL.md
Bluesky
Overview
Bluesky AT Protocol social network — decentralized microblogging. Public read API at public.api.bsky.app, write ops via user's PDS (Personal Data Server).
Workflows
Browse a user's profile and posts
getProfile(actor)→ display name, bio, follower countsgetAuthorFeed(actor)→ user's posts →post.urigetPostThread(uri)→ full post with reply thread
Search and explore
searchActors(q)→ find users →actor.handlegetProfile(handle)→ full profile for a usersearchPosts(q)→ find posts (requires auth)
Feed consumption
getFeed(feed)→ discover/trending posts →post.urigetPostThread(uri)→ expand post with replies
Social graph
getFollowers(actor)→ who follows a usergetFollows(actor)→ who a user follows
Engage with a post
getAuthorFeed(actor)orgetFeed(feed)→ find post →uri,cidlikePost(uri, cid)→ like recordurirepost(uri, cid)→ repost recorduri- Reply:
getPostThread(uri)→ parenturi,cid; thread root →rootUri,rootCid createPost(text, replyTo={uri, cid, rootUri, rootCid})→ replyuri,cid
Undo engagement
getAuthorFeed(actor)orgetPostThread(uri)→ post withviewer.like,viewer.repostunlikePost(uri=viewer.like)→ removes likeunrepost(uri=viewer.repost)→ removes repostdeletePost(uri)→ deletes own post (uri← getAuthorFeed)
Manage follows, blocks, and mutes
getProfile(actor)→did,viewer.following,viewer.blocking,viewer.mutedfollow(subject=did)→ follow recorduriunfollow(uri=viewer.following)→ removes followblockUser(subject=did)→ block recorduriunblockUser(uri=viewer.blocking)→ removes blockmuteUser(actor)/unmuteUser(actor)→ toggle mute (uses handle or DID directly)
Notifications
getNotifications(limit)→ likes, reposts, follows, mentions, replies
Operations
| Operation | Intent | Key Input | Key Output | Notes |
|---|---|---|---|---|
| getProfile | user profile | actor (handle or DID) |
did, handle, displayName, bio, follower/following/post counts | entry point |
| getAuthorFeed | user's posts | actor ← getProfile |
feed[].post (uri, text, author, embeds, counts) | cursor pagination |
| getPostThread | post with replies | uri ← getAuthorFeed/getFeed |
thread.post (text, author, embeds, like/repost/reply/quote/bookmark counts), thread.replies[] | depth param controls reply depth |
| getFeed | custom feed | feed (AT URI of feed generator) |
feed[].post | cursor pagination, use known feed URIs |
| searchPosts | search posts | q |
posts[], hitsTotal | auth via bsky.app (localStorage_jwt) |
| searchActors | search users | q |
actors[] with profile info | cursor pagination |
| getFollowers | user's followers | actor ← getProfile |
followers[] profiles | cursor pagination |
| getFollows | user follows | actor ← getProfile |
follows[] profiles | cursor pagination |
| getPosts | batch fetch posts | uris[] ← getAuthorFeed/getFeed |
posts[] | max 25 URIs |
| createPost | publish post | text, replyTo ← getPostThread (uri, cid, rootUri, rootCid), langs |
uri, cid | auth required, write; replyTo optional |
| deletePost | delete post | uri ← createPost/getAuthorFeed |
success | auth required, write |
| likePost | like post | uri, cid ← getAuthorFeed/getFeed/getPostThread |
like record uri, cid | auth required, write |
| unlikePost | unlike post | uri ← post viewer.like |
success | auth required, write |
| repost | repost | uri, cid ← getAuthorFeed/getFeed/getPostThread |
repost record uri, cid | auth required, write |
| unrepost | undo repost | uri ← post viewer.repost |
success | auth required, write |
| follow | follow user | subject (DID) ← getProfile |
follow record uri, cid | auth required, write |
| unfollow | unfollow user | uri ← profile viewer.following |
success | auth required, write |
| blockUser | block user | subject (DID) ← getProfile |
block record uri, cid | auth required, write |
| unblockUser | unblock user | uri ← profile viewer.blocking |
success | auth required, write |
| muteUser | mute user | actor (handle or DID) |
success | auth required, write |
| unmuteUser | unmute user | actor (handle or DID) |
success | auth required, write |
| getNotifications | notifications | limit, cursor |
notifications[] (reason, author, record) | auth required, cursor pagination |
Quick Start
# Get a user profile
openweb bluesky exec getProfile '{"actor": "bsky.app"}'
# Get a user's posts
openweb bluesky exec getAuthorFeed '{"actor": "bsky.app", "limit": 10}'
# View a post thread (use uri from getAuthorFeed)
openweb bluesky exec getPostThread '{"uri": "at://did:plc:.../app.bsky.feed.post/...", "depth": 6}'
# Browse a trending feed
openweb bluesky exec getFeed '{"feed": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot", "limit": 10}'
# Search users
openweb bluesky exec searchActors '{"q": "developer", "limit": 10}'
# Create a post (requires auth)
openweb bluesky exec createPost '{"text": "Hello world!", "langs": ["en"]}'
# Like a post (requires auth, get uri/cid from feed)
openweb bluesky exec likePost '{"uri": "at://did:plc:.../app.bsky.feed.post/...", "cid": "bafyrei..."}'
# Follow a user (requires auth, get DID from getProfile)
openweb bluesky exec follow '{"subject": "did:plc:..."}'
# Get notifications (requires auth)
openweb bluesky exec getNotifications '{"limit": 10}'