feat(examples): bluesky's seven credential-free reads as a guardfile #92
No reviewers
Labels
No labels
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/mcp-beaver!92
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/bluesky-public-guardfile"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Half of retiring
bluesky-mcp. Companion to #91, which carries the other half.What this is
bluesky-mcpregisters eleven read tools and logs in for all eleven, because it holds one authenticatedBskyAgentand every handler awaits it. That made the whole surface look like it needed a credential. Seven of them do not. Bluesky's public AppView serves them unauthenticated, and this guardfile is those seven.Tool names match the bespoke server exactly, so the public half is a drop-in.
Measured, not assumed
Every status was probed against
public.api.bsky.appon 2026-08-19, and every grant was then served through a locally builtmcp-beaver serveand called end to end.Shipped here, all returning 200 live through the guardfile:
get_profile,search_profiles,get_author_feed,get_posts,get_post_thread,list_followers,list_followsLeft behind, and each for a measured reason:
get_home_timeline-app.bsky.feed.getTimeline, 401list_notifications-app.bsky.notification.listNotifications, 401get_kai_liked_posts-app.bsky.feed.getActorLikes, 400search_posts-app.bsky.feed.searchPosts, 403, which is the one worth flagging. It sits besideapp.bsky.actor.searchActors, which answers 200, so "search" splits across the auth boundary in a way that reads as arbitrary until measured. That asymmetry is upstream's.All four need a session bootstrap, which no auth scheme in this repo can express. That is #91.
Verification performed
just lint-examplesexits 0 with the new file included, listing all seven grants plusmcp_beaver_info.mcp-beaver serve examples/bluesky-public.mcp.kdl: all seven grants returned real payloads with thecoverage-first envelope intact.limit=999returnsquery field "limit": value 999 is above maximum 50uris=[]returnsquery field "uris": array length 0 is below min-items 1urisarray projects to repeated upstream keys, verified against a real post URI.One deliberate break from drop-in
search_profilestakesterm, notquery, which is whatbluesky-mcpcalls it.queryis a reserved opcore engine flag and fails closed at lint - the same wallsteam-storefront.mcp.kdlhit and documented. Renaming the tool instead would have been worse, since the tool name is what a model reaches for. The file says so at the point of the rename.What is lost, recorded in the file rather than discovered later
The trailing comment block names three things, none of which blocks the swap and all of which are real:
bluesky-mcpvalidatesactor,uri, andcursoragainst regexes.restrict ... matchesis a glob, applies to path parameters, and these are all query parameters, so there is no equivalent. What remains is the metachar gate plus the declared types and bounds. Exposure is small becausebase-urlis fixed, so no input can redirect the origin.limitto 20 or 25 per tool anddepth/parentHeightto 3. Bounds are declared here, defaults are not, so an omitted argument now takes the upstream default. Worth a look before this ships.viewer.following,viewer.muted, and friends. An unauthenticated one does not. Irrelevant for reading what an account posts, decisive for anything reasoning about Kai's relationship to an account.What it gains
Every result leads with
coverageand carries the payload underresult, so a truncating harness keeps the caveat rather than destroying it. That is the first invariant of coilyco-gaming/steam-ops#18, arriving for free.Note for the reviewer, not caused by this branch
pre-commit runreports two pre-existingdocumentation-layoutfailures ondocs/s3.md(79 lines against a 40-line cap, 3513 chars against 3000). That file is untouched here and fails the same way on a cleanmain. Every hook that evaluates this branch's file passes,code-commentsincluded. Flagging it because it will block anyone committing to this repo until it is split.Refs #91.
🤖 Generated with Claude Code