noti#
noti is a Bluesky notification manager: it looks at the live inbox, suggests a few actions to reduce noise, and lets you ask for a specific action in plain language.
what it does#
against the live Bluesky API, noti can:
- mute or unmute an account
- turn post notifications on or off for a specific account
- turn reply notifications on or off for a specific account
- mark notifications seen
every mutation is proposed by a model that writes the Bluesky SDK call, runs it in a sandbox with an allow-listed method surface injected, and re-reads appview or PDS state afterward before claiming success. partial failures inside a multi-call script are reported honestly per call.
noti also takes free-form steering guidance (e.g. "normal discourse doesn't warrant a mute") and threads it into the generation prompts so suggestions stay calibrated to your tolerance.
how it works#
the model receives live notification state plus a typed SDK surface (code-mode-inspired) and returns a run(agent, ctx) function. the server:
- validates the code against an allowlist
- executes it in a QuickJS WASM sandbox that queues
{method, input}records - replays each call against the real Bluesky agent, catching and reporting per-call failures
- re-reads the relevant state and diffs before/after — success is only claimed when an observable upstream change occurs
running it#
set these env vars in .env:
ATPROTO_HANDLEATPROTO_PASSWORDANTHROPIC_API_KEY
if self-hosting your own PDS, set ATPROTO_PDS to your PDS URL.
if bsky.social's appview is flaky, set ATPROTO_APPVIEW_PROXY=did:web:api.blacksky.community#bsky_appview to route app.bsky.* reads through Blacksky's appview.
cp .env.example .env
just dev
the app serves on http://127.0.0.1:8000.
tests#
bun test
covers the host-side replay contract — all-ok sequences, mid-sequence failures that must not bypass later calls, and input-payload preservation for failure reporting.
next#
- expand from per-actor activity subscriptions into the broader global notification-preferences surface
- widen the code-mode SDK surface as each added lever gets a clear verification story
- add a daemon ingest process to keep windowed actor occurrences fresh regardless of noti requests
- multi-tenant with OAuth