Chat on FreeQ IRC from inside Obsidian. Clip messages directly into your vault.
- Real-time IRC chat via WebSocket — connect to any FreeQ server
- AT Protocol OAuth — authenticate with your Bluesky/AT Protocol identity via browser, no app password needed
- App-password fallback — works if OAuth setup isn't available
- Guest mode — connect without credentials
- Channel list with unread badges
- Member list toggle
- Message clipping — right-click any message to save it into your vault with a customizable template
- Daily note or folder clipping destinations
- IRCv3 support —
message-tags,server-time,batch,echo-message,chathistory,away-notify,account-notify,extended-join
- Download the latest release (
main.js,manifest.json,styles.css). - Create a folder
.obsidian/plugins/freeq-chat/in your vault. - Copy the three files into that folder.
- In Obsidian, go to Settings → Community plugins → Installed plugins, enable FreeQ Chat.
cd freeq-obsidian
npm install
npm run buildCopy main.js, manifest.json, and styles.css to .obsidian/plugins/freeq-chat/.
OAuth lets you log in with your Bluesky/AT Protocol handle without creating an app password.
One-time setup:
The OAuth flow requires a small callback page that bridges the browser back to Obsidian. The plugin ships with this page in docs/oauth-callback.html.
Host it on GitHub Pages (recommended, free):
- In your repository, go to Settings → Pages
- Set Source to "Deploy from a branch", select
mainand folder/docs - Your callback URL will be:
https://YOUR_USERNAME.github.io/REPO_NAME/oauth-callback.html - Paste this URL into FreeQ Chat settings → OAuth callback URL
Or host it yourself (Netlify, Vercel, your own server):
Just serve oauth-callback.html at any public HTTPS URL and paste it into settings.
Log in:
- Open Settings → FreeQ Chat.
- Under "Log in with AT Protocol", enter your handle (e.g.
alice.bsky.social). - Click Log in.
- A browser window opens. Authorize FreeQ on your PDS.
- The browser redirects back to Obsidian automatically.
- You're connected!
If OAuth doesn't work for your setup:
- Go to bsky.app/settings/app-passwords and create an app password.
- In Settings → FreeQ Chat, enter your DID/handle and the app password.
- Click Connect.
- Click the speech-bubble icon in the left ribbon, or
- Run the command FreeQ: Open chat sidebar (
Ctrl/Cmd + P→ "FreeQ: Open chat sidebar")
- With OAuth: after login, the plugin auto-connects on next launch.
- With app password: click Connect in settings or run FreeQ: Connect to server.
- Type in the input box and press Enter to send.
- Use
/join #channelto join channels. - Use
/partto leave the current channel. - Use
/me does somethingfor actions. - Use
/nick newnickto change your nick.
- Right-click any message in the chat view.
- Select "Clip message to vault".
- The message is appended to your daily note or a folder note (configurable in settings).
In Settings → FreeQ Chat → Clip template, customize the template with variables:
| Variable | Description |
|---|---|
{{text}} |
Message text |
{{from}} |
Sender nick |
{{channel}} |
Channel name |
{{timestamp}} |
ISO timestamp |
{{msgid}} |
Message ULID |
{{url}} |
Permalink (server-dependent) |
Default template:
> {{text}}
> — @{{from}} in {{channel}}, {{timestamp}}
> [msgid: {{msgid}}]This plugin is a lightweight port of the FreeQ web client's IRC stack:
| File | Origin | Notes |
|---|---|---|
src/irc/parser.ts |
freeq-app/src/irc/parser.ts |
Unchanged — pure IRC parser |
src/irc/transport.ts |
freeq-app/src/irc/transport.ts |
Unchanged — WebSocket transport |
src/irc/client.ts |
Adapted from freeq-app/src/irc/client.ts |
No React/Zustand; event-emitting class |
src/ui/ChatView.ts |
New | Vanilla DOM sidebar view |
src/clip/clipper.ts |
New | Obsidian vault writer |
src/auth/oauth.ts |
New | OAuth bridge using obsidian:// protocol |
oauth-callback.html |
Inspired by obsidian-atmosphere | Static redirect bridge |
┌─────────┐ ┌──────────────┐ ┌──────────┐ ┌─────────────┐
│ Obsidian│────▶│ FreeQ Broker │────▶│ PDS Auth │────▶│ Browser │
│ (plugin)│ │ /auth/login │ │ Screen │ │ (user approves)
└─────────┘ └──────────────┘ └──────────┘ └─────────────┘
│ │
│ ┌───────────────┐ │
│◄─────────│ oauth-callback│◄────────────────────────┘
│ │ .html │ (redirects to obsidian://)
│ └───────────────┘
│
▼
┌─────────┐
│Obsidian │ registerObsidianProtocolHandler('freeq-chat', ...)
│(plugin) │
└─────────┘
- Plugin opens browser to FreeQ auth broker (
/auth/login?handle=...&return_to=<callback>) - Broker redirects to PDS auth screen
- User approves → broker redirects to callback page with
#oauth=BASE64 - Callback page decodes data and redirects to
obsidian://freeq-chat?oauth=BASE64 - Obsidian's protocol handler fires → plugin decodes session → stores broker/web tokens
- Plugin connects to IRC using refreshed web token via SASL
ATPROTO-CHALLENGE
- OAuth login via AT Protocol
- App-password fallback
- Message threads / replies
- Message edits & deletes
- Reactions
- Link previews (OpenGraph)
- Encrypted DMs (E2EE)
- Mobile Obsidian optimizations
Same as the FreeQ project.