Forge raw Discord threads into shipped features.
Thread Forge is the teammate who reads every message so you don't have to. It sits in your Discord server during a build, watches the conversation, and quietly turns "someone should really set up auth" into a tracked, assigned, vote-approved card on a live board — then closes that card the moment a matching commit lands. No standups, no spreadsheets, no one asking "wait, who's doing the API?"
It's aimed squarely at the kind of fast, messy, all-hands sprint a hackathon turns into, but the same machinery works for any small team that lives in Discord and ships from GitHub.
A weekend build has a predictable failure mode. The first few hours vanish into coordination — who owns what, what gets built first, whether the database or the endpoints come together — and by the time the team has a plan, a third of the clock is gone. Decisions get buried in scrollback. Tasks get spoken aloud and never written down. Two people build the same thing; nobody builds the other thing.
Thread Forge removes the coordination tax. The conversation is the project tracker. You keep talking the way you already talk; the board keeps itself up to date underneath you.
Everything Thread Forge does is one continuous flow from a sentence in chat to a finished card. This is the whole product in one picture:
flowchart LR
A[Message in Discord] --> B{Gemini reads intent}
B -->|create/update/complete/delete| C[Proposal opened in a thread]
C --> D{Team votes in the thread}
D -->|threshold met| E[Card lands on the Kanban board]
E --> F[Work happens]
F --> G[Commit pushed to GitHub]
G --> H{Fuzzy match vs. open cards}
H -->|score >= 0.6| I[Card auto-moved to Done]
E -.->|"@ThreadForge ..."| J[RAG answers from live project data]
Each stage maps to a real subsystem:
| Stage | What happens | Where it lives |
|---|---|---|
| Read | Gemini classifies each message into an intent and pulls out a task | bot/main.py → app/api/messages → lib/gemini.ts |
| Decide | A proposal opens in its own thread; the team votes by replying naturally | app/api/proposals, lib/vote-analyzer.ts |
| Track | Approved work becomes a draggable card synced to everyone | app/dashboard, components/KanbanBoard.tsx |
| Automate | Pushed commits are matched to open cards and close them | app/api/github/webhook, lib/github-matcher.ts |
| Ask | Anyone can query the live board in plain English | app/api/rag, lib/rag.ts |
Reading the room. Every message in the watched channel is run through Google's Gemini 2.5 Flash, which decides whether it's asking to create, update, complete, or delete work — and, when it's a new task, infers the type, priority, and which specialties should own it. If the AI quota runs dry, a keyword-based fallback keeps things moving so the bot never goes silent.
Routing by skill, not by who spoke. Tasks are assigned from what the work is, matched against a library of 16+ engineering roles — backend, frontend, full-stack, design, QA, DevOps, data science, mobile, security, DBA, PM, product, scrum, tech writing, business analysis, and solution architecture. The person who asked for something isn't automatically the person who has to build it.
Decisions that need a quorum. Bigger items don't hit the board on one person's say-so. Each proposal spins up a Discord thread, and the bot reads the replies to tally approvals — Gemini interprets "yeah go for it" and "approved, but use JWT" as votes without anyone clicking a button. Thresholds are configurable per type (features need more sign-off than a quick todo), the original requester counts as an automatic yes, and you can't set a bar higher than your headcount.
A board that maintains itself. The dashboard is a real-time Kanban with drag-and-drop columns, per-person filtering, live counts, and badges that surface priority and difficulty only when they're worth showing. Everyone sees the same state at the same time.
Commits that close tickets. Point a GitHub webhook at Thread Forge and every push is compared against the open cards. A fuzzy matcher scores the overlap; clear the confidence bar and the card slides to Done on its own, with the match logged so you can see why.
A bot you can interrogate. Mention @ThreadForge and ask anything about the current state — who's on what, what's blocked, what's left. A retrieval step pulls the relevant tasks, comments, and logs, and Gemini answers from that live context rather than guessing.
A paper trail. Every create, update, completion, deletion, and automated GitHub action is written to an activity log with the actor and a timestamp.
| Layer | Built with |
|---|---|
| Web app | Next.js 16.1, React 19.2, TypeScript 5, Tailwind CSS 4 |
| Board UI | @hello-pangea/dnd for drag-and-drop, lucide-react icons |
| API | Next.js route handlers (REST), session-based auth via lib/auth.ts |
| Data | MongoDB 7 (Atlas or local) — database name threadforge |
| Intelligence | Google Gemini 2.5 Flash (@google/generative-ai) for intent, voting, and RAG |
| Chat bot | Python 3.11.2, discord.py 2.3.2, aiohttp 3.9.1, python-dotenv |
You'll need Node 18+, Python 3.11.2, a MongoDB connection (Atlas is easiest), a Discord application with a bot token, and a Gemini API key.
1 — Get the code and the web dependencies.
git clone https://github.com/ak2106-47/Thread-Forge
cd Thread-Forge
npm install2 — Set up the Python bot in its own virtual environment. Confirm your interpreter first — python --version should print Python 3.11.2; if it doesn't, install that version (pyenv, conda, or the official installer all work).
cd bot
python -m venv .venv
source .venv/bin/activate # Windows PowerShell: .\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt3 — Add your secrets. Create .env.local in the project root:
# Discord
DISCORD_BOT_TOKEN=
DISCORD_CHANNEL_ID=
DISCORD_WEBHOOK_URL=
# MongoDB
MONGODB_URI=
# Google Gemini
GEMINI_API_KEY=
# App URLs
NEXTAUTH_URL=http://localhost:3000
API_BASE_URL=http://localhost:30004 — Start both halves. The web app and the bot run side by side:
# terminal one — Next.js app + API
npm run dev
# terminal two — Discord bot (with the venv active)
cd bot
python main.pyOpen http://localhost:3000 and create your account.
In the Discord Developer Portal, create an application and add a bot. The one setting people forget is Message Content Intent — switch it on, or the bot can't read anything. Drop the token into .env.local, then generate an invite from the OAuth2 URL Generator with the bot and applications.commands scopes and the Send Messages, Read Message History, and Create Public Threads permissions. Invite it to your server, right-click the channel you want it to watch, copy the ID, and set DISCORD_CHANNEL_ID.
GitHub integration is optional and toggled in Settings. To turn it on, open your repo's Settings → Webhooks → Add webhook, set the payload URL to https://your-domain.com/api/github/webhook, choose the application/json content type, add the secret you configured in Settings, and subscribe to just the push event. For local testing, expose your machine with ngrok so GitHub can reach the endpoint. After that, a commit like "Implemented landing page responsive design" will close a card named "Landing Page Design" on its own.
Spinning up a project. Sign up, pick your role(s), and open Settings to name the project, tune approval thresholds (defaults: feature 2, bug 1, todo 1), and add teammates — manually or by linking their Discord accounts.
Creating work. Just say it in the channel:
You: I need an API for user authentication
Bot: 📜 Proposal: "User Authentication API"
Pending — 1/2 approvals · Priority: Medium
(discussion thread opened)
Prefer clicking? The dashboard's New Task button does the same thing by hand.
Approving it. Reply in the proposal's thread however you'd normally talk:
You: approved, but let's use JWT
Bot: ✅ Vote counted — 2/2. Approved!
"User Authentication API" is now on the board.
Finishing it. Push your work and let the webhook do the rest:
$ git commit -m "Implemented user authentication API with JWT"
$ git push
→ matched "User Authentication API" → moved to Done ✅
Checking status. Ask the bot:
You: @ThreadForge what is Alice working on?
Bot: 🤖 Thread Forge Assistant
Alice is on:
• User Authentication API — In Progress
• Landing Page Design — To Do
All routes live under /api.
Auth
| Method | Route | Purpose |
|---|---|---|
| POST | /api/auth/signup |
Register a user |
| POST | /api/auth/signin |
Log in |
| POST | /api/auth/signout |
Log out |
| GET | /api/auth/session |
Read the current session |
Tasks
| Method | Route | Purpose |
|---|---|---|
| GET | /api/tasks |
List tasks |
| POST | /api/tasks |
Create a task |
| PATCH | /api/tasks |
Move a task (drag-and-drop) |
| DELETE | /api/tasks?id={id} |
Delete a task |
| POST | /api/tasks/update |
Edit task details |
| POST | /api/tasks/comment |
Comment on a task |
Proposals
| Method | Route | Purpose |
|---|---|---|
| GET | /api/proposals |
List pending proposals |
| POST | /api/proposals/vote |
Cast a vote |
| DELETE | /api/proposals?id={id} |
Reject a proposal |
Settings, integrations & misc
| Method | Route | Purpose |
|---|---|---|
| GET / PATCH | /api/settings |
Read / update project settings |
| POST | /api/settings/users |
Add a teammate |
| GET | /api/users |
List teammates |
| POST | /api/github/webhook |
Receive push events |
| GET | /api/github/webhook |
Health check |
| POST | /api/rag |
Ask a plain-English question |
| GET | /api/logs |
Activity log |
Intent detection (lib/gemini.ts). A message becomes structured data before it ever touches the database. Gemini returns the intent, the task type, the suggested roles, a priority, and a confidence score — for example, "I need a new design for the landing page" resolves to a feature, roles ["designer", "frontend"], medium priority, ~0.92 confidence. Assignment then keys off those roles, not off whoever happened to type the message.
Commit matching (lib/github-matcher.ts). When a push arrives, each commit message is reduced to its meaningful keywords, scored against every open card by how much of the card's keywords it covers, and boosted for multi-word hits. Anything at or above 0.6 confidence is treated as a completion and the card moves itself to Done. A commit such as "Fixed database integration bug" lines up with a card "Fix database integration" at roughly 0.87 and closes it.
Vote reading (lib/vote-analyzer.ts). Replies in a proposal thread are interpreted rather than counted literally, so a casual "ship it" registers as approval and a "no, too risky" does not.
Question answering (lib/rag.ts). Questions to the bot trigger a retrieval pass over current tasks, comments, and logs; that context is handed to Gemini so answers reflect the board as it stands right now.
Thread-Forge/
├── app/
│ ├── page.tsx # landing page
│ ├── dashboard/ # the Kanban board
│ ├── proposals/ # pending-proposal view
│ ├── settings/ # project + team + integration config
│ ├── logs/ # activity log view
│ ├── auth/ # sign-in / sign-up screens
│ └── api/ # all route handlers (see HTTP API)
├── bot/
│ ├── main.py # the Discord listener + responder
│ └── requirements.txt
├── components/
│ ├── KanbanBoard.tsx
│ ├── NewTaskModal.tsx
│ └── TaskDetailModal.tsx
├── lib/
│ ├── gemini.ts # intent detection
│ ├── rag.ts # question answering
│ ├── vote-analyzer.ts # thread vote interpretation
│ ├── github-matcher.ts # commit → card fuzzy matching
│ ├── auth.ts / check-auth.ts # sessions
│ └── db.ts # MongoDB client (database: threadforge)
├── types/ # shared TypeScript types
├── public/ # logo + PWA manifest
└── middleware.ts
| Symptom | Things to check |
|---|---|
| Bot ignores messages | Message Content Intent enabled? Bot can read the channel? DISCORD_CHANNEL_ID correct? Any Python tracebacks in terminal two? |
| Commits don't close cards | Is the webhook URL publicly reachable (ngrok for local)? Secret matches Settings? Push event subscribed? Check the webhook's Recent Deliveries. |
| Messages aren't analyzed | GEMINI_API_KEY valid and within quota? Watch the Gemini dashboard for rate limits — the keyword fallback should still fire even when the API is down. |
| Database won't connect | MONGODB_URI formatted correctly? IP allowed in Atlas network access? User has read/write? Try connecting with MongoDB Compass to isolate it. |
Released under the MIT License — use it, fork it, ship it.
Built on the shoulders of Google Gemini, Discord's bot platform, MongoDB Atlas, and a long list of excellent open-source libraries.