The AI-native platform that turns raw RFPs into winning proposals β automatically.
Companies juggle dozens of RFPs every quarter, each demanding hours of cross-referencing inventory, benchmarking competitors, and writing polished proposals from scratch. BidForge eliminates that grind. Upload an RFP document and a five-agent AI pipeline takes over β parsing requirements, matching line items against your product catalog via RAG, pulling live market pricing through SerpAPI, and synthesizing a competitive pricing strategy. Before the final PDF is generated, you review and select from recommended pricing options, keeping humans in the loop where it matters. The result is a branded, ready-to-send proposal document uploaded to S3 in minutes, not days.
Homepage |
Dashboard |
Inventory Management |
RFP Exploration |
Summarised Pricing Options |
Final Proposal Artifact |
- 5-Agent AI Pipeline β Parse β Explore β Summarise β Generate, each agent is independent and composable
- Intelligent RFP Parsing β Extracts requirements, flags missing fields, and cleans raw text using Gemini 2.5 Flash via OpenRouter
- Inventory RAG β Matches RFP line items against your uploaded product catalog (PDF, CSV, TXT) stored in S3
- Competitor Intelligence β Analyzes uploaded competitor files + fetches live market prices via SerpAPI (IQR-cleaned median pricing)
- Semantic Search on Past RFPs β Vector embeddings (HuggingFace
all-MiniLM-L6-v2) stored in MongoDB Atlas with$vectorSearchfor cross-RFP learning - Human-in-the-Loop Pricing β Summariser presents 2β3 pricing strategy options per line item; user selects before document generation
- PDF Export β Final proposal rendered from Markdown β PDF via
md-to-pdf(Puppeteer) with branded styling, uploaded to S3 - Email Ingestion β Cloudflare Worker receives inbound emails and triggers the pipeline automatically
- Company Auth β Email verification flow via Resend, JWT-based session middleware
- Monorepo β Bun workspaces with shared
commonpackage for type-safe event schemas
sequenceDiagram
participant U as User / Email
participant FE as Frontend (React 19)
participant BE as Backend (Fastify)
participant P as Parser Agent
participant E as Explore Agents
participant S as Summariser Agent
participant D as Document Agent
participant DB as MongoDB Atlas
participant S3 as AWS S3
U->>FE: Upload RFP document
FE->>BE: POST /api/rfp/upload
BE->>DB: Store RFP + embedding
FE->>BE: POST /api/rfp/:id/parse
BE->>P: runParseTextStep()
P-->>BE: Parsed requirements + missing fields
BE->>DB: Update status β "parsed"
FE->>BE: POST /api/rfp/:id/explore
BE->>E: runExploreStep() [Inventory + Competitor in parallel]
E-->>BE: Inventory analysis + Competitor pricing markdown
BE->>DB: Update status β "explored"
FE->>BE: POST /api/rfp/:id/summarise
BE->>S: runSummariseStep() + search_past_rfps tool
S-->>BE: Pricing options per line item
FE->>U: Show pricing options for review
U->>FE: Select preferred pricing options
FE->>BE: POST /api/rfp/:id/generate-document
BE->>D: generateFinalDocument()
D-->>BE: Markdown proposal
BE->>S3: Upload PDF
BE-->>FE: Return S3 document URL
bidforge/
βββ apps/
β βββ backend/ # Fastify API + AI agents (Bun)
β β βββ src/
β β β βββ agent/ # 5 AI agents + LLM config
β β β βββ routes/ # auth/, company/, rfp/
β β β βββ utils/ # embedding, pricing, s3-client
β β βββ prisma/ # MongoDB schema
β βββ frontend/ # React 19 + TanStack Router
β β βββ src/
β β βββ components/
β β βββ routes/
β β βββ store/
β βββ email-worker/ # Cloudflare Worker (email ingestion)
β βββ common/ # Shared Zod schemas (EmailEvent)
βββ assets/ # Screenshots & banner
| Layer | Technology |
|---|---|
| Runtime | Bun |
| Backend Framework | Fastify 5 |
| Frontend | React 19, TanStack Router, Tailwind CSS v4 |
| AI / LLM | LangChain, @langchain/openrouter (Gemini 2.5 Flash Lite) |
| Embeddings | HuggingFace Inference (all-MiniLM-L6-v2) |
| Vector Search | MongoDB Atlas $vectorSearch |
| Database ORM | Prisma 6 (MongoDB) |
| File Storage | AWS S3 (via Bun's S3Client) |
| Market Pricing | SerpAPI (Google Shopping) |
| PDF Generation | md-to-pdf (Puppeteer) |
| Email Worker | Cloudflare Workers |
| Email Sending | Resend |
| Animations | Framer Motion, GSAP, Lenis |
- Bun β₯ 1.3
- MongoDB Atlas cluster with a Vector Search index named
vector_indexon theRFPcollection, pathembedding - AWS S3 bucket
- Accounts / API keys for: OpenRouter, HuggingFace, SerpAPI, Resend
git clone https://github.com/yashraj-n/bidforge.git
cd bidforge
bun installCreate a file at apps/backend/.env with the following variables:
| Variable | Description | Required |
|---|---|---|
DATABASE_URL |
MongoDB Atlas connection string | β |
OPENROUTER_API_KEY |
OpenRouter API key (for Gemini 2.5 Flash) | β |
HUGGINGFACE_API_KEY |
HuggingFace Inference API token | β |
AWS_REGION |
AWS region for S3 | β |
AWS_ACCESS_KEY_ID |
AWS access key | β |
AWS_SECRET_ACCESS_KEY |
AWS secret key | β |
S3_BUCKET |
S3 bucket name | β |
SERP_API_KEY |
SerpAPI key (live market pricing) | |
RESEND_API_KEY |
Resend API key (email verification) | β |
JWT_SECRET |
Secret for JWT signing | β |
cd apps/backend
bunx prisma generate
bunx prisma db pushImportant
You must manually create a Vector Search index in the MongoDB Atlas UI on the RFP collection:
- Index name:
vector_index - Field path:
embedding - Dimensions:
384 - Similarity:
cosine
# Backend (port 9000)
cd apps/backend && bun run dev
# Frontend (port 3000)
cd apps/frontend && bun run dev| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/signup |
β | Register a new company |
POST |
/api/login |
β | Login, receive JWT |
GET |
/api/me |
β | Get current company profile |
POST |
/api/company/add-inventory |
β | Upload inventory file to S3 |
GET |
/api/company/inventory |
β | List inventory items |
POST |
/api/company/add-competitor |
β | Upload competitor file + AI analysis |
GET |
/api/company/competitors |
β | List competitors |
POST |
/api/rfp/upload |
β | Create RFP record with embedding |
POST |
/api/rfp/:id/parse |
β | Run Parser Agent |
POST |
/api/rfp/:id/explore |
β | Run Inventory + Competitor Agents |
POST |
/api/rfp/:id/summarise |
β | Run Summariser Agent |
POST |
/api/rfp/:id/generate-document |
β | Generate PDF proposal |
GET |
/api/rfp/:id |
β | Get RFP details |
GET |
/api/rfp |
β | List all RFPs |
POST |
/api/rfp/:id/reject |
β | Reject an RFP |
POST |
/api/rfp/:id/reset |
β | Reset RFP to initial state |
GET |
/api/rfp/stats |
β | Get RFP pipeline statistics |
GET |
/api/rfp/search |
β | Semantic search across RFPs |
stateDiagram-v2
[*] --> uploaded
uploaded --> parsed : /parse
parsed --> exploring : /explore triggered
exploring --> explored : agents complete
explored --> summarised : /summarise
summarised --> generating_document : /generate-document
generating_document --> completed : PDF uploaded to S3
uploaded --> rejected : /reject
parsed --> rejected : /reject
explored --> rejected : /reject
exploring --> failed : agent error
generating_document --> failed : PDF error
Contributions are welcome! Here's how to get started:
- Fork the repository
- Create a feature branch:
git checkout -b feat/your-feature - Commit your changes: use Conventional Commits (
feat:,fix:,chore:,docs:) - Push to your fork and open a Pull Request
Branch naming conventions:
| Prefix | Use case |
|---|---|
feat/ |
New features |
fix/ |
Bug fixes |
docs/ |
Documentation changes |
Note
Please open an issue before starting work on large changes so we can discuss the approach.
This project is licensed under the Apache License 2.0 β see the LICENSE file for details.
If BidForge saves your team hours on proposals, consider giving it a β
Built with β€οΈ by
@yashraj-n,
@rsk807,
@dhiraj-rajput,
@ashish9925







