agent-routing
Decide which model, effort level, and cascade shape each subagent gets, and how to keep improvement loops safe…
Browse Bluesky content via API and firehose - search posts, fetch user activity, sample trending topics, read feeds and lists, analyze and categorize accounts. Supports authenticated access for personalized feeds. Use for Bluesky research, user monitoring, trend analysis, feed
$ npx -y skills add oaustegard/claude-skills --skill browsing-bluesky --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/browsing-blueskyContext preview
The summary Claude sees to decide when to auto-load this skill.
Browse Bluesky content via API and firehose - search posts, fetch user activity, sample trending topics, read feeds and lists, analyze and categorize accounts. Supports authenticated access for personalized feeds. Use for Bluesky research, user monitoring, trend analysis, feed
name: browsing-bluesky description: Browse Bluesky content via API and firehose - search posts, fetch user activity, sample trending topics, read feeds and lists, analyze and categorize accounts. Supports authenticated access for personalized feeds. Use for Bluesky research, user monitoring, trend analysis, feed reading, firehose sampling, account categorization. metadata: version: 0.7.1
Access Bluesky content through public APIs and real-time firehose. Supports optional authentication for personalized feeds. Includes account analysis for categorization.
Add skill directory to path and import:
import sys
sys.path.insert(0, '/path/to/skills/browsing-bluesky') # or use .claude/skills symlink path
from browsing_bluesky import (
# Core browsing
search_posts, get_user_posts, get_profile, get_feed_posts, sample_firehose,
get_thread, get_quotes, get_likes, get_reposts,
get_followers, get_following, search_users,
# Trending
get_trending, get_trending_topics,
# Account analysis
get_all_following, get_all_followers, extract_post_text,
extract_keywords, analyze_account, analyze_accounts,
# Authentication utilities
is_authenticated, get_authenticated_user, authenticated_identity,
clear_session
)Authentication enables personalized feeds (like Paper Skygest) that require knowing who's asking.
1. Create an app password at Bluesky: **Settings → Privacy and Security → App Passwords** 2. Set environment variables:
export BSKY_HANDLE="yourhandle.bsky.social" export BSKY_APP_PASSWORD="xxxx-xxxx-xxxx-xxxx"
Two credential pairs are recognised, and the prefix is the only difference:
| Pair | Identity | |---|---| | `MUNINN_BSKY_HANDLE` / `MUNINN_BSKY_APP_PASSWORD` | `muninn` — preferred | | `BSKY_HANDLE` / `BSKY_APP_PASSWORD` | `owner` — used when no Muninn pair is set |
`BSKY_IDENTITY=muninn|owner` picks one outright, and a pair named that way is never substituted for: asking for `muninn` with no Muninn pair set reads as public rather than quietly reading as the owner. An unrecognised value raises.
This matters because a booted container holds **both** pairs. Until 2026-08-28 the unprefixed one won, so every authenticated read — the following timeline, and the mutes, blocks and labelers that shape all of them — came back as the account owner with nothing in the output saying so, from a skill documented as read-only that was nonetheless holding an app password carrying write scope on his account. On a machine with only the documented `BSKY_*` pair, nothing changes.
`BSKY_IDENTITY` is configuration, not auth failure, and raises instead
if is_authenticated():
print(f"Logged in as: {get_authenticated_user()}")
else:
print("Using public access")
# Which pair answered — a handle alone does not say whether it was chosen
# or simply the only one set.
authenticated_identity() # {'identity': 'muninn', 'handle': ..., 'did': ...}
# Clear session if needed (e.g., switching accounts or identities)
clear_session()Use `search_posts()` with query syntax matching bsky.app advanced search:
Combine query syntax with function params for complex searches.
1. Fetch profile with `get_profile(handle)` for context (bio, follower count, post count) 2. Get recent posts with `get_user_posts(handle, limit=N)` 3. For topic-specific user content, use `search_posts(query, author=handle)`
**Recommended workflow** — trending API first, firehose for deep dives:
topics = get_trending_topics(limit=10)
# Returns: {topics: [{topic, display_name, description, link}, ...],
# suggested: [...]}trends = get_trending(limit=10)
for t in trends:
print(f"{t['display_name']} — {t['post_count']} posts ({t['status']})")
# Each trend includes: topic, display_name, link, started_at,
# post_count, status, category, actorsposts = search_posts(trend["topic"], limit=25)
**Prerequisites**: Install Node.js dependencies once per session:
cd /home/claude && npm install ws https-proxy-agent 2>/dev/null
data = sample_firehose(duration=30) # Full firehose sample data = sample_firehose(duration=20, filter="python") # Filtered sample
Returns dict with keys:
`get_feed_posts()` accepts:
A collection of Claude skills distributed as a Claude Code plugin marketplace. Skills are primarily designed for the Claude.ai PaaS skill compute environment; mileage will vary if used as Claude Code Agent Skills.
Decide which model, effort level, and cascade shape each subagent gets, and how to keep improvement loops safe…
Cross-context adversarial review for deliverables before shipping. Use when producing blog posts, technical recommendations,…
Convenes expert panels for problem-solving. Use when user mentions panel, experts, multiple perspectives, MECE, DMAIC, RAPID, Six…
Routes, triages, flags and rates a piece of text with a probability for every option: which department or queue a ticket goes to,…
Delegates work to a subagent or spawned session by writing only the task, while a PreToolUse hook pages the parent transcript…
Chooses how to launch subagents from Claude Code (the Agent tool, a Workflow script, or headless claude -p children) and runs a…