ATProto-based AI Assistant Chat interface.

Files
README.md

Shared Computer Network AI Assistant Chat #

SCN Chat is an ATProto AI assistant chat interface allowing users to use their AT Protocol spaces capable PDS to host their chat history.

Status: early development. atproto spaces are in alpha, so expect breaking changes and do not store anything sensitive.

Note: If using a spaces enabled PDS it must have been built on the 2026-10-22 spaces alpha or later (currently optional). Earlier alpha PDSs are not compatible.

How it works #

  • Every chat is its own space. Each conversation lives in a permissioned space on the user's PDS.
  • Sharing uses the space's read policy. A chat can be shared read-only with specific people, or made public to anyone with an atproto account.
  • Your PDS is the API. Any client can hold a conversation by writing records directly to the PDS. See lexicons/README.md for the conventions.
  • Bring your own keys. Users can add API keys for any provider, admins can configure models for everyone. Any OpenAI-compatible endpoint is supported.
  • No spaces yet? Due to the alpha nature of permissioned spaces, the first phase of this app supports storing chats in the app's own database. Users still need an atproto account to sign in.

Features #

  • One-on-one chat with streaming replies
  • Read-only sharing
  • Image attachments for vision models
  • PDF text extraction
  • Automatic chat titles
  • Chat history search
  • Web search and page fetch plugins
  • User and admin model configuration
  • Role management
  • Model and thinking effort chosen per message, with model search

TODO #

  • Image generation, as a plugin
  • PDF OCR
  • Speech to text and text to speech
  • Encrypted conversations. See specs/encrypted-conversations.md
  • Memories
  • MCP servers as tools
  • Browser and push notifications, and an installable PWA
  • Move plugin settings and tool switches to the user's PDS, through a generic plugin settings lexicon
  • Migrate chats between local storage and spaces, in both directions
  • Provider-native tools, such as built-in web search, for the models that support them
  • Web search for models without tool calling, by generating queries before the reply
  • Web fetch through external services such as Firecrawl or Tavily extract, for pages that need JavaScript
  • YouTube transcripts in web fetch
  • Tabs on the Jump to layer for the chat's sources, code blocks, images, and files, each jumping to its reply
  • A library of every image, file, and source across the user's chats, each linking back to its message
  • Continue in a new chat from a message, copying the branch up to it and linking back to where it came from
  • Compare the versions of a reply side by side, as columns, and keep the best one
  • A command palette for chats, messages, and actions, from the browser's local copy
  • Pinned chats, above Today in the chat list, through an optional field on the index entry

Getting started #

Requirements: #

  • Node 22.18 or newer (Node 24 is recommended)
  • pnpm 10.33 or newer
  • An ATProto account to sign in with.
  • A spaces enabled PDS (currently optional)

Setup #

  1. Install dependencies: pnpm install
  2. Run pnpm setup-env. It creates .env from .env.example and fills in freshly generated OAUTH_PRIVATE_KEYS and SECRET_KEY, leaving any secret you already set alone.
  3. Put your DID in ADMIN_DIDS so you can login and configure the application.

Start the app #

  1. Run pnpm dev, or pnpm dev --scan to also load React Scan, which outlines components as they render.
  2. Open http://127.0.0.1:3000 and sign in with your ATProto handle.

To try the production build on this machine, run pnpm preview instead. It builds the web app, then starts the server in production mode at the same address.

To test from a phone or another device, run pnpm dev:remote, or pnpm preview:remote for the production build. Either runs the server behind a localhost.run tunnel, which needs only ssh and no account, and prints an HTTPS URL to open in place of 127.0.0.1. It needs OAUTH_PRIVATE_KEYS. The URL changes on every run, and localhost.run can change it during a long one too, so if signing in stops working, run it again. The free tunnel is slow, so the first load takes a while. A Cloudflare quick tunnel would be faster, but it holds back a reply's stream until the reply ends.

  1. Open Settings > Admin to add your plugins and models, and choose who else can sign in.

Deploying #

See docs/deployment.md.

Extending #

Model providers, tools, file ingesters, and turn hooks are all plugins, so anyone can build their own integration. See:

License #

MIT