Authenticated read-only Bluesky MCP with a fixed, bounded AT Protocol tool surface.
  • TypeScript 77.1%
  • Python 6.6%
  • Just 6.4%
  • Shell 5.7%
  • Dockerfile 2.8%
  • Other 1.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Kai Ase Siren 182ae740dd
All checks were successful
build-publish / validate (push) Successful in 18s
build-publish / publish (push) Successful in 2m30s
chore: drop CODEOWNERS so agents stop reading a review request as a gate
Forgejo auto-requested Kai's review on every agent pull request because this
repo carried `* @coilysiren`. Branch protection runs `required_approvals: 0`, so
that request never blocked a merge, it only ever looked like one. A standing
review request from the repo owner contradicts the landing lane in the one place
an agent checks before deciding whether it may act.

Fleet sweep tracked at coilyco-bridge/agentic-os-kai#889.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 02:13:30 -07:00
.agents/skills/repo-bluesky-mcp feat: add repository pointer skill 2026-07-30 10:12:50 -07:00
.forgejo/workflows chore: drop CODEOWNERS so agents stop reading a review request as a gate 2026-08-20 02:13:30 -07:00
.github chore: drop CODEOWNERS so agents stop reading a review request as a gate 2026-08-20 02:13:30 -07:00
.ward feat(just): retire ward exec, move the verb table to a justfile 2026-08-17 13:39:34 -07:00
docs feat(just): retire ward exec, move the verb table to a justfile 2026-08-17 13:39:34 -07:00
scripts chore: adopt the managed pre-commit suite and declare the small band 2026-08-16 21:19:14 -07:00
src chore: adopt the managed pre-commit suite and declare the small band 2026-08-16 21:19:14 -07:00
test feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
.dockerignore feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
.gitignore feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
.pre-commit-config.yaml chore: adopt the managed pre-commit suite and declare the small band 2026-08-16 21:19:14 -07:00
AGENTS.md feat(just): retire ward exec, move the verb table to a justfile 2026-08-17 13:39:34 -07:00
CLAUDE.md chore: adopt the managed pre-commit suite and declare the small band 2026-08-16 21:19:14 -07:00
Dockerfile feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
eslint.config.js feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
justfile feat(just): retire ward exec, move the verb table to a justfile 2026-08-17 13:39:34 -07:00
LICENSE feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
package-lock.json feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
package.json feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00
pyproject.toml chore: adopt the managed pre-commit suite and declare the small band 2026-08-16 21:19:14 -07:00
README.md feat(just): retire ward exec, move the verb table to a justfile 2026-08-17 13:39:34 -07:00
tsconfig.json feat: build authenticated read-only Bluesky MCP 2026-07-23 10:39:50 +00:00

bluesky-mcp

bluesky-mcp is Kai's authenticated, strictly read-only Bluesky MCP. It uses the official AT Protocol SDK to create and refresh an internal app-password session, and the official MCP SDK streamable-HTTP transport to serve a small, reviewed tool surface.

Transport and configuration

The process serves GET /healthz and MCP streamable HTTP at POST /mcp. Defaults are HOST=0.0.0.0 and PORT=9113. Set these runtime variables:

  • BSKY_APP_PASSWORD (required): app password supplied only at runtime.
  • BSKY_HANDLE (optional): authenticated account handle; defaults to coilysiren.me.
  • MCP_ALLOWED_HOSTS (optional): comma-separated hosts accepted by the MCP transport's DNS-rebinding defense. It defaults to local development hosts.

Run locally with an app password supplied out of band:

just install
BSKY_APP_PASSWORD=... just run

Exact tool inventory

  1. get_profile
  2. search_profiles
  3. search_posts
  4. get_author_feed
  5. get_posts
  6. get_post_thread
  7. list_followers
  8. list_follows
  9. get_home_timeline
  10. list_notifications
  11. get_kai_liked_posts

All page sizes are bounded to 50 or below. Post batches are capped at 25 and thread depth plus parent height at 6.

Threat model

The configured app password can authorize account writes, so the adapter must never expose that authority. It has no post, reply, follow, like, repost, delete, mute, block, report, moderation, chat, account mutation, login, generic URL, arbitrary XRPC, or raw HTTP tool. Inputs accept only bounded, validated actors, post AT URIs, cursors, queries, and limits. The app password and session tokens remain in process memory and credential-shaped result fields are stripped before an MCP response is created. SDK failures are deliberately logged without their values.

The source image runs as the non-root node user. Deployment access control, secret injection, and network exposure are intentionally outside this source repository.

Development

just lint, just typecheck, just test, ward audit, and just precommit are the supported validation verbs. A main-branch workflow tests and publishes the private image forgejo.coilysiren.me/coilyco-flight-deck/bluesky-mcp:<full-source-sha>. Deployment uses a separate read-only forgejo-registry pull credential.

See also