Someone on our team pastes a founder's funding application into a Discord channel. Four minutes later there's an anonymised, investor-ready brief, three matched investors with intro emails, and a list of the questions an investor would ask in the first minute. Then everything stops, and waits for a human to type approve.
We built that in four days for the Flip the Switch hackathon, with four Claude Code agents and Switch. We had never built anything with Switch before.
This post is the guide we wish we'd had on day one. It walks through every step we took, the exact commands, and the mistakes that cost us time, so you can get your own agents working in team chat faster than we did.
This post has three parts:
- What we made: a desk of four agents and a human that turns funding applications into investor briefs.
- How we set it up: every step from an empty laptop to agents working in Discord, with the exact commands, in seven steps.
- What we learned: the ideas that made Switch click for us, and a cheat sheet of the gotchas that cost us time.
Code, template and samples: github.com/ABHIGYA0205/bizowl-brief-desk
The problem we were solving
BizOwl helps early-stage founders in India's Tier-2 and Tier-3 cities raise money. Founders apply through a fundraising form we share in our 400+ member WhatsApp community, and for each application our team writes a one-page brief from an investor's point of view. The founder's name and contact details are hidden, so investors judge the startup first.
By hand, that means reading a long application, cross-checking every number, scrubbing every name and link, and working out which investors might care. It's slow, and the mistakes are expensive:
- A phone number or a co-founder's name slips into a brief that was meant to be anonymous.
- A red flag goes unnoticed, like a startup calling itself "Scaling" while raising a pre-seed round.
- A startup gets pitched to an investor whose stage or cheque size doesn't fit.
We didn't want a chatbot that does all of this in one go. We wanted a small team of agents, one job each, working in the same chat as us, where we could see every step and make the final call. That's exactly the shape of thing Switch is built for.
What we made
Brief Desk is a Discord channel where four agents and the BizOwl team work an application from start to finish:
- A team member pastes a founder's application into
#brief-desk. - intake checks it against our form. If something's missing, it drafts a WhatsApp message for us to send the founder. It also lists the questions an investor would ask.
- analyst writes the investor brief.
- privacy strips every personal detail and checks the brief against the application.
- matcher picks three investors, drafts intro emails, and stops.
- A person types
@matcher approve Saffron only. Only then is the approved brief and email posted to a separate#investor-outreachchannel.
Each agent hands off to the next by mentioning it, so the whole team can watch every step happen in the channel. Here's the 3-minute demo:
Now, how we set it up.
Switch in 60 seconds
Switch is open-source plumbing that puts AI agents into team chat. It doesn't ship agents or models: you bring both, and Switch connects them. Five words to know before you start:
| Word | What it means |
|---|---|
| Switch server | The thing that holds everything together. You can run it on your own laptop in Docker, for free. |
| Switch Console | The desktop app. It starts the local server, runs your agents, and connects your chat apps. |
| Agent | An AI coding agent you already use. Our Console (v0.40.1) listed Claude Code, Codex, Cursor, OpenCode and Antigravity as providers. Other agents can join through Switch's agent protocol. |
| Bridge | The connection to a chat app: Slack, Microsoft Teams, Discord, Telegram, or Mattermost, which comes built into the local server. |
| Room | Every connected channel becomes a room: a shared log that people and agents read from, with its own instructions, roles and documents. |
The mental model that clicked for us: the room is the team's shared brain, and agents are teammates who join it. Everything good in our project came from putting things in the room instead of inside each agent.
Step 1: Install the three pieces (about 20 minutes)
You need Docker, an AI agent, and Switch Console. We used a Mac; Console also has early-access Windows and Linux builds.
1. Docker Desktop. Install it, open it, and leave it running. Switch's local server runs inside it.
2. Claude Code. In Terminal:
curl -fsSL https://claude.ai/install.sh | bash claude --version If you get command not found: claude, the install worked but your shell can't find it yet. This fixed it for us:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc source ~/.zshrc Then run claude, sign in through the browser, and type /exit.
Optional but worth it: give Claude Code Switch's docs, so it can answer Switch questions while you build.
claude mcp add switch-docs --transport http https://docs.switchagents.ai/mcp 3. Switch Console. Download it from the Switch releases page (arm64 for Apple silicon, x64 for Intel). On first launch it asks how you want to run Switch: pick On this computer. It installs the server in Docker and starts it. The first start downloads a few GB, so this is a good time for chai.
You're set up when the sidebar says your local server is running, and Settings → Agent providers shows Claude Code as Signed in. If it says the CLI isn't installed, quit Console completely (Cmd + Q) and reopen it: it reads your PATH once, at startup.
Console greets you with switch-buddy-admin, an assistant agent for setting up Switch itself. Remember that name. It did most of our setup work.
Step 2: Connect a chat app (we picked Discord)
You can skip this step entirely and use the Mattermost that comes with the local server. We wanted Discord because two of us needed to be in the room, and on a local server only you can sign in to its Mattermost. Connecting a real chat app is how teammates reach your agents.
Our founders live on WhatsApp, which isn't one of Switch's bridges. Rather than fight it, we kept WhatsApp as the front door (that's where the form link is shared) and ran the agent desk in Discord. We also looked at Telegram, but Discord let Switch create channels for us, and it renders tables and threads nicely.
Create the bot:
- In the Discord Developer Portal, create an application, open Bot, reset the token and copy it. Treat it like a password.
- On the same page, turn on Server Members Intent and Message Content Intent. Miss this and your agents see no messages.
- Under OAuth2 → URL Generator, tick
botandapplications.commands, and give it: View Channels, Send Messages, Send Messages in Threads, Manage Webhooks, Manage Channels, Manage Roles, Read Message History, Attach Files, Add Reactions. Open the URL and add the bot to your server. - In Discord, turn on Developer Mode (User Settings → Advanced), right-click your server and Copy Server ID.
Connect it in Console: Home → Messaging apps → Connect → Discord, paste the token and server ID. Then Link my account and pick your own Discord account.
Wake up a channel: post any ordinary message in it. The bot replies that it linked the channel to a new Switch room. Until then, commands like !invite-agent quietly do nothing.
Two things we learned the hard way:
- Link the right account. We first linked one teammate's Discord account as the server owner, so switch-buddy-admin ignored the other one. You can fix it under the Discord connection's menu with Change my account….
- Teammates don't need their own Switch account. On a local server they can't have one anyway. Agents set to answer "anyone in this room" reply to everyone in the channel. Only owner-only agents, like switch-buddy-admin, ignore people who aren't linked.
Step 3: Build by talking to switch-buddy-admin
This was the biggest surprise of the hackathon. We barely clicked through settings pages. Instead we invited Switch's admin agent into our channel and asked it to do things:
!invite-agent @switch-buddy-admin Room instructions are text every agent in the room reads when it joins, and they take priority over an agent's usual defaults. We asked buddy to set ours:
@switch-buddy-admin please set these room instructions for this room: This room is BizOwl Brief Desk. BizOwl turns founder applications into anonymised, investor-ready briefs. Rules for every agent: - Only respond when someone addresses you by name. - Keep messages short. Use headings and bullets, no long paragraphs. - Privacy: never write a founder's name, phone number, email, social handles or home address in any brief or message. - When your step is done, hand off by mentioning the next agent by name. - Nothing is final until a BizOwl team member types "approve". - If information is missing or unclear, say so. Never invent numbers or facts. Creating an agent was one message too:
@switch-buddy-admin create a Claude Code agent named intake, working directory /Users/you/bizowl-brief-desk, and add it to this room. Its instructions: ... Buddy didn't just follow orders. Before building, it showed a plan and asked us two real questions: should the agent ask before risky actions (we said yes, so a human stays in control), and who can talk to it (we said anyone in the room, so both of us could). It also noticed that new agents were auto-added to the default Mattermost rooms and removed them, and later caught a gap in our own design before we hit it.
One tip: keep buddy in your test channel only. Before recording a demo, use clean channels without it, so viewers only see your own agents.
Step 4: Four agents, one job each
We split the work so each agent does one thing well, and so every step is visible to the team:
| Agent | Job |
|---|---|
| intake | Checks every field on our form. If something is missing, drafts a short WhatsApp message for us to send the founder. Lists "Questions an investor will ask". |
| analyst | Writes a 9-part brief using only facts from the application. Anything unclear is marked "to confirm". |
| privacy | Strips names, phone numbers, emails, LinkedIn and pitch deck links, and checks every number in the brief against the application. |
| matcher | Picks three investors, explains each fit, drafts intro emails, then waits for a human. |
Hand-offs are just mentions. Each agent's instructions end with "when you're done, mention the next agent". intake posts @analyst ready for brief…, analyst posts @privacy brief ready for privacy check…, and so on. Because it all happens in the room, the team watches every hand-off happen and can step in at any point.
Switch puts agent replies in threads. This tripped us up once: we answered intake's question as a new message in the channel, and intake had lost the context. Reply inside the agent's thread (the "1 Message ›" link) and it remembers everything.
Agents only see what happens after they join, and they only hear messages that mention them by their exact name. If an agent seems to ignore you, check both. !list-agents shows who's in the room.
Step 5: Roles, and the bug that would have broken our desk
A role in Switch isn't a label on an agent. It's a hat with its own instructions: an agent picks it up while it's working and drops it when its session ends. That's powerful, because the job ("privacy reviewer") is defined separately from whoever does it. Later, you can move the job to a different agent without redesigning the workflow.
We asked buddy to create two roles, brief-analyst and privacy-reviewer, and to make hand-offs mention the role names instead of the agents. Buddy pushed back before building, and it was right.
Its explanation, in short: a role mention only reaches an agent that's holding the role at that moment. Our agents only run while they're working, and they drop their role when they go idle. So between applications nobody would hold the role, the hand-off would reach nobody, and the application would just sit there. Switch would only post a warning that no one has the role.
The fix was simple once we understood it. Each hand-off now mentions both, like brief-analyst (analyst). The agent's name is what wakes it up; the role shows which job it's doing. And each agent takes its role every time it starts, so in the room you see:
analyst: 🎭 assumed the brief-analyst role. Two small things: role names can't contain spaces (privacy-reviewer, not "privacy reviewer"), and a role shouldn't share its name with an agent, or mentions get confusing. Roles are exclusive, so only one agent holds each at a time.
Step 6: Shared data, a second room, and a human at the end
Room documents. matcher needs an investor list. Instead of pointing each agent at a file, we asked buddy to add investors.sample.csv as a document in the room, so every agent sees the same data. Worth knowing: it's a copy, not a link. Edit the CSV on disk later and the room's copy doesn't change until you add it again.
Linked rooms. Approved briefs shouldn't sit in the noisy working channel. We asked buddy:
@switch-buddy-admin create a new room #investor-outreach on Discord, link it to this room, and update matcher so that after approve it also posts the approved brief and emails in #investor-outreach It created the channel, linked the two rooms both ways ("approved briefs go here" / "where briefs are prepared"), and updated matcher. Now the working room and the clean output room are separate, and matcher knows where each one is.
The human in the loop. matcher never finishes on its own. It posts its three matches and drafts, then asks us to approve, and it only hears an approve that mentions it:
@matcher approve Saffron only Only the Saffron email gets saved and posted to the outreach room, with a note of who approved it. The other two drafts are dropped. That one message is both the control and the audit trail, and it's the moment we're proudest of: the agents do the slow work, and a person makes the call.
We added one more rule for testing on real applications. Any message that starts with @intake REAL: keeps every file for that application in a git-ignored private/ folder and only ever posts to the private outreach room. That let us test on real data without risking it ending up in our public repo or demo.
Step 7: Package the whole thing as one template
Once the desk worked, we asked buddy to save it as a template. It read each agent's current settings from disk and wrote one YAML file holding all four agents, all four rooms, the roles, the links and the investor list. We exported it from Templates in Console and committed it to our repo.
Here's a trimmed slice, so you can see how readable it is:
params: machine: { type: machine, label: Machine } directory: { type: directory, label: Working folder } bridge: { type: bridge, label: Messaging app } resources: intake: type: agent provider: claude machine: "{machine}" directory: "{directory}" auto_approve: false # ask before risky actions addressing: {anyone_in: [desk, desk_live]} desk: type: room name: brief-desk bridge: "{bridge}" agents: [intake, analyst, privacy, matcher] roles: - name: brief-analyst exclusive: true - name: privacy-reviewer exclusive: true docs: - name: investors.sample.csv desk_group: type: group links: - {from: desk, to: outreach, label: approved briefs go here} - {from: outreach, to: desk, label: where briefs are prepared} Whoever uses the template answers three questions: which machine runs the agents, which working folder they share, and which chat app to create the channels in. Console offers the built-in Mattermost as an option there, so you can try it without setting up Discord.
Two things to check before you publish a template:
- Clear out personal paths. Our export had our own Mac's folder path as the default working folder. On anyone else's machine that path doesn't exist, so we deleted it.
- Names must be unique. "Use template" on the same server warned us that an agent called intake already existed. Templates are for a fresh server, or for after you've removed the originals.
Gotchas cheat sheet
Every one of these cost us between five minutes and an hour. Hopefully they cost you nothing.
| Symptom | What's going on | Fix |
|---|---|---|
command not found: claude | Installed, but not on your PATH | Add ~/.local/bin to PATH, then restart Switch Console |
| Console says Claude Code CLI isn't installed | Console reads PATH once, at startup | Quit with Cmd + Q and reopen |
!invite-agent does nothing | The channel isn't a Switch room yet | Post any ordinary message in it first |
| Discord agents see no messages | Privileged intents are off | Turn on Server Members and Message Content intents |
| switch-buddy-admin ignores a teammate | It only answers its owner, and that account isn't linked | Link the right account, or let teammates talk to your own agents set to "anyone in this room" |
| An agent ignores you | Not mentioned by its exact name, or the message is from before it joined | Mention @name exactly; !list-agents shows who's there |
| An agent forgot the context | You replied in the channel, not its thread | Reply inside the agent's thread |
| An agent goes silent mid-task | A permission prompt is waiting, often inside a thread | Open the thread or Console and allow it |
| A hand-off goes nowhere | You mentioned a role nobody holds right now | Mention the agent's name too, e.g. brief-analyst (analyst) |
| Everything stops for hours | Four agents share one Claude subscription's usage limit | Budget runs; test with short inputs |
| buddy can't change a room | It isn't a member of that room | Add it first, or use the room's page in Console |
| Two rooms overwrite each other's files | Both share one working folder | Send each item through one room only |
Discord thread titles look like <@&1567...> | Mentions in thread names show as raw role IDs | Cosmetic; collapse threads before recording |
What it caught
We tested on five fictional applications, each built to stress one agent. These moments convinced us that splitting the work across agents in one room was the right call:
- The analyst made something up, and privacy caught it. The application said the CTO built "2 apps with 50k+ downloads". The brief said "each". Privacy flagged that word, plus two other claims that weren't in the application, and marked all three "to confirm". One agent checking another is exactly what you lose with a single do-everything prompt.
- Personal data hidden in plain text. One founder put her name, email, phone and LinkedIn inside her answers and asked to hide her company name. Privacy removed all of it, and matcher even named the output files
healthtech-tier2instead of the company. - Credit isn't revenue. Rs 1.1 crore of credit tracked through a kirana app could easily read as revenue. intake flagged it, and every agent after it, investor emails included, kept the distinction.
- Honest matching. No investor on our list backed spacetech. Instead of forcing a fit, matcher said so, called two options weak and recommended one. We approved just that one.
Then we ran one real BizOwl application through it, privately. About four minutes of agent time from paste to "Type approve to finalise". intake found six questions an investor would ask, including a pre-revenue startup hoping to close in a month and partnerships with nobody named. A text search of the finished brief found zero team names, links or contact details.
The real application also taught us something no test case did: real founders name their whole team in the team section and drop Drive links everywhere. We rebuilt intake around our actual form's fields, and taught privacy to strip every person's name and every link, not just the founder's.
What we learned
Six lessons from four days, in the order they clicked for us:
- Put things in the room, not in the agents. Our privacy rules, the investor list and the roles live in the room, so we wrote each once and every agent shares it. Copy them into four separate agents and they'd drift apart the first time you edit one. This is the single biggest idea in Switch.
- One job per agent beats one big prompt. Splitting the work meant one agent could check another. privacy caught the analyst inventing a detail; a single do-everything agent would have been checking its own work.
- switch-buddy-admin is a co-builder, not a help page. Describe what you want in plain words, read the plan it shows you, and answer its questions. It caught two design mistakes before we hit them: role-only hand-offs, and a privacy agent that couldn't find files in a new folder.
- A name wakes an agent; a role says what it's doing. Hand-offs need both. It's the one Switch behaviour we'd tell every first-time builder about.
- Test on real data early, safely. Our fictional applications were tidy. The first real one had team names, mentor names and Drive links everywhere, and we updated all four agents because of it. A simple
REAL:tag kept it out of our public repo. - Keep a human at the end. Agents that stop and wait for "approve" are agents a team actually trusts. And in a chat room, the approval is also the audit trail, for free.
What's next for Brief Desk
- Sending new form submissions straight into the desk, so nobody has to paste them
- Limiting approval to a BizOwl role, so only named people can say yes
- Using BizOwl's real investor network as the room document
- Moving it to a shared Switch server, so the whole team can use it
Links
- Code, template and sample applications: github.com/ABHIGYA0205/bizowl-brief-desk
- Demo video: youtube.com/watch?v=08uIkZkuxsc
- Switch: switchagents.ai · docs · 10-minute quickstart
Built by team Room_Mates (Anurag Kumar and Abhigya) for the Flip the Switch hackathon by WeMakeDevs, DevTools Academy and Switch. #HowISwitch



