Running inone command.
It asks for your Anthropic key once, then starts Switch, a Mattermost to try it in, Ferri and Desk in Docker, with a demo event already loaded. No Node, no Switch checkout.
$ git clone https://github.com/RudraO2/Ferri.git$ cd Ferri$ ./ferri up
On Windows, the last command is .\ferri up in PowerShell, or ferri up in cmd.
Try before you install
Ferri is live for Lantern Build Night, a made-up event. Ask @ferri when does hacking start?, then something it can't know. Or look around a live Desk, read-only.
Requirements
What you need.
Nothing else: no Node, no Switch checkout.
- DockerDocker Desktop on Windows and macOS, or Docker Engine with the compose plugin v2.20 or newer on Linux.
- About 4 GB of free RAM8 GB is comfortable.
- About 8 GB of diskThe first run downloads about 3 GB.
- An Anthropic API keyFrom console.anthropic.com, under API keys.
What ./ferri up does
Five steps, done for you.
- 1Asks for your Anthropic key onceThen generates every other secret into .env.
- 2Pulls the imagesOr builds Ferri's image from the checkout if it cannot pull it. The first run takes several minutes.
- 3Starts the stack and waits until it is healthySwitch (core, dashboard, Postgres), Mattermost, Ferri's Postgres, Ferri and Desk.
- 4Sets up Switch and a demo eventRegisters Ferri in Switch, creates the rooms ferri-lab and ferri-crew, the test people meera, arjun (members) and priya (crew), and loads Lantern Labs and its event, Lantern Build Night.
- 5Prints the addresses, the logins and three messages to tryRunning it again changes nothing that is already set.
What you get
Four addresses on your own machine.
The passwords are printed by ./ferri up and kept in .env: MATTERMOST_USER_PASSWORD, MM_TEST_PASSWORD and GATEWAY_ADMIN_PASSWORD.
- Mattermostthe chat to try Ferri inhttp://localhost:8065user and the printed password. meera, arjun and priya share a second printed password.
- Deskthe organizers' dashboardhttp://localhost:3100[email protected] and the printed password
- Ferri Pocketthe crew's phone apphttp://localhost:3100/mSame as Desk
- Switch dashboardSwitch's own Gateway UIhttp://localhost:3300Same as Desk
- Also running: the Switch API at
localhost:8800, used by Ferri and the scripts, and Ferri's Postgres atlocalhost:5433. - Every port is bound to 127.0.0.1 only. To change one, set
DESK_HOST_PORT,MATTERMOST_HOST_PORT,API_HOST_PORT,GATEWAY_HOST_PORTorFERRI_DB_HOST_PORTin .env, then./ferri up.
Try it
Three messages in Mattermost.
Open http://localhost:8065, go to ferri-lab, and watch one unknown question go to the crew and come back.
- 1 ferri-labyou @ferri when does hacking start?
Ferri answers with the time and a Source line.
- 2 ferri-labyou @ferri can I bring my dog?
The demo knowledge doesn't cover it, so Ferri says it is checking with the crew, and a question card opens in ferri-crew.
- 3 ferri-crewyou, as crew A1 "Yes, dogs are welcome"
Or tap a button on the card. Ferri answers the asker in ferri-lab and remembers it, so the next person gets the answer at once.
Also try does anyone know the wifi password? in ferri-lab, with no mention. Ferri waits a short moment so a person can answer first, then answers with its source.
Connect your apps
One command per app.
Each command adds the platform's connection to Switch, which makes every group on it a Switch room. A value you leave out is read from .env, and it is safe to run again.
Telegram
Make a bot with BotFather, turn Group Privacy off before adding it anywhere, then add it to the group.
Discord
Create an application, turn on the Server Members and Message Content intents, invite the bot, then post once in the channel to create the room.
Slack
Create the app from Switch's manifest (Socket Mode, no public URL), make an xapp- token with connections:write, install it and /invite it.
Through the whatsapp_web bridge we added to Switch, linked to your own number. It is already in the Switch image; only the sidecar is extra. In .env, add the profile and name the chats that become rooms:
COMPOSE_PROFILES=mattermost,whatsapp FERRI_WHATSAPP_CHATS=me,Lantern Build Night
Then start the sidecar and pair. The command prints a pairing code: on the phone, WhatsApp, Linked devices, Link a device, Link with phone number instead. Leave out --code to get a QR code instead.
Then, on any app
- 1Type
!invite-agent @ferriin the chat. The space shows up in Desk under Discovered, switched off. - 2Attach it to the event in Desk, or with
./ferri space attach <space> --mode auto. Use--crewfor the room where cards land.
Name the platform bot after Switch, not after Ferri. Slack and Discord turn a typed @ferri into a mention of a bot whose name starts with “ferri”, and then the message never reaches Ferri.
Read platforms.mdOptional parts
Each one is off until you turn it on.
./ferri doctor shows which are on, off or broken, and the next step for each. After you edit .env, run docker compose restart ferri desk.
Shield
Blocks scam links and link floods, and redacts leaked keys, on every message.
shield.md$ ./ferri shield:connectPocket push
The crew's phones buzz when a card needs them.
pocket.mdKeys are generated. Phones need HTTPS: set FERRI_PUBLIC_URL and run a tunnel.Email
Partner outreach and guest emails through Resend.
email.mdSet RESEND_API_KEY and FERRI_EMAIL_FROM$ ./ferri email:setupSocial
Posts on LinkedIn, X and Instagram through Buffer.
social.mdSet BUFFER_API_KEY, plus FERRI_MEDIA_URL and FERRI_MEDIA_SECRET for imagesBuilder
A coding agent Switch runs on your machine: the event site, posters, listings.
builder.mdOn the host, with Node 22 and Claude Code:$ pnpm install$ pnpm builder:setup$ pnpm builder:controllerPosters
Background art for the Builder's posters.
builder.mdSet OPENAI_API_KEY$ pnpm builder:setupLuma API
Lists events through Luma's API instead of the Builder's browser.
builder.mdSet LUMA_API_KEY (Luma Plus only)Without Mattermost
On a small server that uses Telegram or Discord, remove
mattermostfromCOMPOSE_PROFILESin .env.
Useful commands
Everything goes through ./ferri.
On Windows, use .\ferri in PowerShell or ferri in cmd.
Something off?
Run ./ferri doctor first. If Ferri does not answer at all, the Anthropic key is usually wrong or out of credit.
./ferri upStart everything. The first run asks for the key and writes .env. Safe to run again../ferri downStop. Keeps your data../ferri resetStop and delete all data. Asks you to type yes. Keeps .env../ferri logs [service]Follow the logs: ferri, desk, switch, mattermost, ferri-setup, ..../ferri psWhat is running../ferri doctorCheck the core of the stack and every optional part: on, off or broken, with the next step../ferri connect listList the platform connections in Switch../ferri space listSee the rooms Ferri is in../ferri space attach <space> --mode autoAttach a room to the event (or --crew for the crew room)../ferri smokeAsk Ferri through Mattermost and check it answers with a source. CI runs this../ferri buildBuild Ferri's image from this checkout instead of pulling it../ferri pullPull the newest images../ferri <script> [args]Run any package.json script in the stack: kb list, kb ask "<question>", card:preview, ...
Hosting on a server
Our live demo runs exactly this way.
The same ./ferri up, on a small always-on Linux server with Docker and about 3 GB of free RAM, reached through a Cloudflare named tunnel. No ports are opened on the server, and Mattermost is off: your community uses Telegram, Discord or Slack.
- 1Make a Cloudflare named tunnel
cloudflared tunnel create ferri - 2Clone the repo on the server and fill in .env
COMPOSE_FILE=compose.yml:infra/demo/compose.demo.yml - 3Start it
./ferri up - 4Connect your platform and attach its chats
./ferri space attach build-night --mode auto - 5Turn on Shield
./ferri shield:connect - 6Cap what strangers can spend with a Switch budget
"metric": "messages", "amount_limit": 300, "period_hours": 24 - 7Check it
./ferri doctor
Cost
Free software. You pay only for your own model use.
Free and MIT
Ferri is MIT-licensed and runs on your own machine or server, next to your own Switch. Switch itself is licensed by SandboxAQ under its own terms.
Your own Anthropic usage
Your key, your bill. The quick jobs on every message (triage, care reading, sheets, translations) run on Claude Haiku 5.5. Answers and drafts default to Claude Sonnet 5.5; set FERRI_MODEL_MAIN=claude-haiku-5-5 to run them on Haiku too.
Caps you control
A Switch budget can stop Ferri for the day after a set number of messages, and the Builder has its own Switch budget. Also set a monthly spend limit on the Anthropic key.
Clone it. Run it. Ask it something.
CI boots the whole stack with ./ferri up on a clean runner and asks Ferri through Mattermost on every push to main. Your machine is next.

