A modern full-stack web application that allows users to search the web for any topic, scrape content from multiple websites, and generate comprehensive AI-powered summaries using Google Gemini API. All summaries can be saved to a personal Vault and downloaded in multiple formats.
MindBrief is an AI-powered research assistant that helps you quickly understand complex topics by:
- Searching the web for relevant sources
- Extracting and cleaning content from multiple websites
- Generating comprehensive summaries using Google Gemini AI
- Organizing your research in a personal vault
- Exporting summaries for offline use
- Web Search: Search for any topic and discover relevant websites
- Content Scraping: Extract content from multiple websites with intelligent parsing
- AI Summarization: Generate comprehensive, single-page summaries from scraped content
- Download Summaries: Download summaries as TXT or formatted documents
- Vault Storage: Save and manage your summaries in a personal vault
- Firebase Authentication: Secure user authentication and data storage
- Modern UI: Beautiful, responsive interface with smooth animations
Backend:
cd backend
npm installFrontend:
cd frontend
npm installYou need to run two servers simultaneously:
Terminal 1 - Backend:
cd backend
npm run devTerminal 2 - Frontend:
cd frontend
npm run devOpen your browser and navigate to: http://localhost:3000
- Search: Enter a topic and click "Search" to find relevant websites
- Select Links: Click on links in the sidebar to select them for summarization
- Generate Summary: Click "Generate Summary" to create a comprehensive document
- Download: Click the download button to save your summary as a file
- Save to Vault: Save summaries for later access in your personal vault
Create a .env file in the backend folder:
# Required for AI Summarization
GEMINI_API_KEY=your_gemini_api_key_here
# Optional: For persistent vault storage
# See Firebase Admin section below
# Optional: Server port (default: 5000)
PORT=5000
# Optional: Frontend URL for CORS (default: http://localhost:3000)
FRONTEND_URL=http://localhost:3000Getting a Gemini API Key:
- Go to Google AI Studio
- Sign in with your Google account
- Click "Create API Key"
- Copy the key and add it to your
.envfile
Note: Without a Gemini API key, the system will still work and provide formatted summaries from scraped content (no AI enhancement).
Create a .env.local file in the frontend folder:
# Firebase Configuration (Required for Authentication)
NEXT_PUBLIC_FIREBASE_API_KEY=your_firebase_api_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=your_measurement_idSetting up Firebase:
- Go to Firebase Console
- Create a new project or select existing one
- Enable Authentication (Email/Password and Google)
- Enable Firestore Database
- Go to Project Settings > General
- Scroll down to "Your apps" and add a web app
- Copy the configuration values to your
.env.localfile
For persistent vault storage that survives server restarts, add one of the following to backend/.env:
Option 1: Service Account JSON (Recommended)
FIREBASE_SERVICE_ACCOUNT={"type":"service_account","project_id":"...","private_key_id":"...","private_key":"...","client_email":"...","client_id":"...","auth_uri":"...","token_uri":"...","auth_provider_x509_cert_url":"...","client_x509_cert_url":"..."}Option 2: Project ID (uses application default credentials)
FIREBASE_PROJECT_ID=your-project-idOption 3: Path to service account JSON file
GOOGLE_APPLICATION_CREDENTIALS=./path/to/service-account-key.jsonNote: Without Firebase Admin, vault uses in-memory storage (data resets on server restart). To get a Firebase service account:
- Go to Firebase Console
- Select your project
- Go to Project Settings > Service Accounts
- Click "Generate New Private Key"
- Copy the JSON content to
FIREBASE_SERVICE_ACCOUNTin your.envfile
- Ensure backend is running:
cd backend && npm run dev - Check health: Visit
http://localhost:5000/api/health - Verify port 5000 is not in use
Windows:
netstat -ano | findstr :5000
taskkill /PID <PID> /FLinux/Mac:
lsof -ti:5000 | xargs killcd frontend
rm -rf node_modules
npm install
npm run devMindBrief-AI_Summarizer/
βββ backend/ # Express.js API server
β βββ src/
β β βββ routes/ # API route handlers
β β β βββ auth.js # Authentication routes
β β β βββ search.js # Search and scraping routes
β β β βββ summarize.js # AI summarization routes
β β β βββ vault.js # Vault storage routes
β β βββ server.js # Main server file
β βββ package.json # Backend dependencies
β βββ requirements.txt # Backend requirements list
β βββ .env # Environment variables (create this)
βββ frontend/ # Next.js frontend
β βββ src/
β β βββ app/ # Next.js app router pages
β β β βββ dashboard/ # Main dashboard page
β β β βββ login/ # Login/signup page
β β β βββ page.tsx # Home page
β β βββ components/ # React components
β β β βββ vault.tsx # Vault component
β β β βββ auth-guard.tsx # Auth protection
β β β βββ ui/ # UI components
β β βββ lib/ # Utilities
β β βββ api.ts # API client
β β βββ firebase.ts # Firebase config
β β βββ auth-context.tsx # Auth context
β βββ package.json # Frontend dependencies
β βββ requirements.txt # Frontend requirements list
β βββ .env.local # Frontend env vars (create this)
βββ README.md # This file
βββ workflow.txt # Detailed project workflow
npm start- Start production servernpm run dev- Start with auto-reload
npm run dev- Start development servernpm run build- Build for productionnpm start- Start production server
GET /api/health- Health checkPOST /api/search- Search for websitesPOST /api/search/scrape- Scrape content from URLPOST /api/summarize- Generate summary from URLsGET /api/vault/:userId- Get user's vault itemsPOST /api/vault/:userId- Save item to vaultDELETE /api/vault/:userId/:itemId- Delete vault item
cd backend
npm install
# Or use requirements.txt as referencecd frontend
npm install
# Or use requirements.txt as reference- Search: Uses DuckDuckGo to find relevant websites for your topic
- Scraping: Intelligently extracts main content from selected URLs
- AI Processing: Sends content to Google Gemini API for summarization
- Storage: Saves summaries to Firebase Firestore or in-memory storage
- Export: Allows downloading summaries as TXT or Markdown files
- Frontend: Next.js 15 with React 19, TypeScript, Tailwind CSS
- Backend: Express.js with Node.js
- AI: Google Gemini API for summarization
- Database: Firebase Firestore (optional, with in-memory fallback)
- Authentication: Firebase Authentication
User visits app β Login/Sign Up page
β
User authenticates via Firebase Auth
β
Auth state checked by AuthGuard component
β
If authenticated β Redirect to Dashboard
If not authenticated β Stay on Login page
User enters topic in search box
β
Frontend: api.search.searchTopic(topic)
β
Backend: POST /api/search
β
Backend scrapes DuckDuckGo search results
β
Backend extracts URLs and titles
β
Backend filters out search engine URLs
β
Backend returns list of links
β
Frontend displays links in sidebar
User clicks on links in sidebar
β
Frontend: toggleLinkSelection(url)
β
Selected links stored in state (selectedLinks array)
β
Selected links highlighted with checkmark
β
User can select/deselect multiple links
User clicks "Generate Summary" button
β
Frontend: api.summarize.summarizeUrls(topic, selectedLinks)
β
Backend: POST /api/summarize
β
Backend validates URLs (skips search result pages)
β
Backend scrapes content from each URL in parallel:
- Sends HTTP GET request with proper headers
- Parses HTML with Cheerio
- Extracts main content (article, main, content containers)
- Removes unwanted elements (nav, footer, ads, etc.)
- Cleans and formats content
β
Backend filters valid content (length > 30 chars)
β
If Gemini API key configured:
- Combines all content
- Sends to Gemini API (gemini-1.5-flash model)
- Gets AI-generated summary
Else:
- Creates formatted summary from scraped content
β
Backend returns summary with sources
β
Frontend displays summary in main content area
User clicks "Save to Vault" button
β
Frontend: api.vault.saveItem(userId, {topic, summary, sources})
β
Backend: POST /api/vault/:userId
β
Backend checks Firebase Admin initialization:
If Firebase Admin configured:
- Saves to Firestore collection "vaults"
- Document ID = userId
- Stores items array with new item
Else:
- Saves to in-memory Map (inMemoryVault)
β
Backend returns success response
β
Frontend shows success message
β
Vault automatically opens
User clicks "Vault" button
β
Frontend: api.vault.getItems(userId)
β
Backend: GET /api/vault/:userId
β
Backend checks Firebase Admin:
If Firebase Admin configured:
- Queries Firestore for user's vault document
- Returns items array
Else:
- Returns items from in-memory Map
β
Frontend displays list of saved summaries
β
User can click on any summary to view details
β
User can delete summaries
User clicks download button (TXT or Markdown)
β
Frontend: downloadText() or downloadMarkdown()
β
Creates blob with summary content
β
Creates download link
β
Triggers browser download
β
File saved to user's downloads folder
Frontend (React Component)
β
Frontend API Client (lib/api.ts)
β
HTTP Request to Backend
β
Backend Express Router
β
Route Handler (routes/*.js)
β
Business Logic
β
External Services (Gemini API, Firebase, Web Scraping)
β
Response back through chain
Frontend Error Handling:
- API Request fails β Catch error in try-catch block β Log to console β Show user-friendly alert β Update backend status to "offline"
Backend Error Handling:
- Route handler catches error β Logs error details β Returns appropriate HTTP status code β Returns error message in JSON response
Scraping Error Handling:
- URL scraping fails β Error caught in scrape promise β Returns error object with URL and error message β Failed URLs filtered out β If all URLs fail β Return error response β If some URLs succeed β Continue with valid content
Authentication:
- User login/signup β Firebase Auth validates credentials β JWT token generated β Token stored in browser β Protected routes check auth state β API requests include user ID from auth context
Rate Limiting:
- Request arrives at backend β Express rate limiter middleware checks β If within limit β Process request β If exceeded β Return 429 Too Many Requests
CORS:
- Frontend makes request β Backend CORS middleware checks origin β If origin allowed β Add CORS headers β Request proceeds
- Parallel Scraping: All URLs scraped simultaneously
- Content Filtering: Removes unnecessary content early
- Caching: In-memory vault for fast access
- Rate Limiting: Prevents abuse
- Error Recovery: Graceful fallbacks
- Rate Limiting: Prevents API abuse
- CORS Protection: Only allows requests from configured frontend
- Helmet.js: Adds security headers
- Firebase Auth: Secure user authentication
- Input Validation: Validates all user inputs
- Frontend: Next.js 15, React 19, TypeScript, Tailwind CSS
- Backend: Express.js, Node.js
- AI: Google Gemini API (gemini-1.5-flash)
- Database: Firebase Firestore (optional)
- Authentication: Firebase Authentication
- Scraping: Cheerio, Axios
- Set environment variables on your hosting platform
- Run
npm installin the backend directory - Start server with
npm start
- Set environment variables (NEXT_PUBLIC_*)
- Run
npm run build - Deploy the
.nextfolder or usenpm start
- Vercel: Great for Next.js frontend
- Railway/Render: Good for backend Express.js
- Firebase Hosting: Can host both with proper configuration
- Backend must be running before using the frontend
- Vault storage is in-memory by default (configure Firebase for persistence)
- AI summarization requires Gemini API key for best results
- All web scraping is done server-side to avoid CORS issues
- See
workflow.txtfor detailed project workflow documentation
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License
Ogshub
Happy Summarizing! π
For detailed workflow information, see workflow.txt