No auth scheme survives a session bootstrap, which is the single blocker on retiring both bluesky-mcp and steam-ops' authenticated half #91
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#91
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Filed by Olaf (ops seat,
claude) after tracing why two bespoke MCPs cannot follow reddit-mcp onto a guardfile. Kai's stated goal is retiring reddit-mcp, bluesky-mcp, and steam-ops. Reddit is done. The other two are blocked on the same missing capability, and it is this one.What exists
The grammar offers four auth schemes, all resolving a static value per request from env or SSM:
auth none- examples/reddit.mcp.kdl, examples/steam-storefront.mcp.kdlauth bearer- examples/skillsmp.mcp.kdl, examples/sidecar.mcp.kdlauth header-token- examples/forgejo-issues.mcp.kdlauth query-param- examples/steam-web-api.mcp.kdlGrepping
docs/forcreateSession,login,refresh.token, or a client-credentials exchange returns nothing. There is no scheme where the runtime performs a first request to obtain a credential and then presents the result on subsequent requests.Why that blocks bluesky-mcp
Its deploy README says the manifest injects an existing Bluesky app password via ExternalSecret. AT Protocol turns an app password into a session through
com.atproto.server.createSession, which returns anaccessJwt(short-lived) and arefreshJwt. Every authenticated read presents theaccessJwt, and it must be refreshed. No scheme above can express that.The surface splits cleanly, which is the useful part. I probed
public.api.bsky.appunauthenticated just now:auth none-app.bsky.actor.getProfile,app.bsky.feed.getAuthorFeed,app.bsky.feed.getPostThread,app.bsky.graph.getFollowers,app.bsky.graph.getFollows,app.bsky.actor.searchActorsapp.bsky.feed.getTimeline,app.bsky.notification.listNotificationsapp.bsky.feed.searchPostsSo of the source's 11 read tools, roughly 7 could ship as a credential-free guardfile immediately, the same
auth noneshape steam-storefront uses.get_home_timeline,list_notifications,search_posts, and Kai's likes need this issue closed first. (app.bsky.feed.getPostsI did not probe and is inferred public from its family.)Why that blocks steam-ops only partially
Steam's web-api and storefront halves are already guardfiles shipped to both Sirens lanes. The remaining plane is client/PICS, and it needs two things this repo does not have: a session bootstrap, and a websocket. The websocket half is against a stated design invariant -
docs/DESIGN.mdhas a section titled "Network HTTP, never stdio" and the runtime binds exactly one HTTP listener - so I am not asking for it here and do not think it should happen. Steam's PICS plane is likely a permanentserve-upstreamcase rather than a guardfile case. Its own failure is tracked at coilyco-gaming/steam-ops#13.Naming it so this issue is not later read as covering steam end to end. Closing this unblocks bluesky. It does not retire steam-ops.
The shape worth considering
Reddit's retirement needed three upstream capabilities that did not exist when it started:
raw-response(umbra#289),auth none(umbra#303), andextract as="feed-entries"(mcp-beaver#81). That is the pattern - each bespoke retirement surfaces the gap that was hiding inside the bespoke code. This is bluesky's.Sketch, not a design:
Open questions a design has to settle, listed because they are the hard part rather than the grammar:
serve-upstreamalready documents a one-long-lived-session decision for its own upstream, and the reasoning there may transfer.accessJwtmust never reach a tool result, a log line, or an error string.Acceptance
lintcatches a malformed session block offline.Not asked for here
Websocket or any non-HTTP transport. See the steam paragraph above.