FindX discovers businesses, analyzes their websites, and writes personalized outreach emails β all on autopilot using 3 agents .
Ψ§ΩΨΉΨ±Ψ¨ΩΨ© | English
Three AI agents work in sequence, fully automated:
- Research Agent β Finds businesses matching your query across multiple countries (Netherlands, UK, Germany, France, Belgium, USA, UAE, and more) via local business registries and Google Places APIs. Supports searches in English, Dutch, and Arabic.
- Analysis Agent β Audits each website with Lighthouse, detects tech stack, scores 0β100, identifies opportunities including AI/automation potential and revenue leakage
- Outreach Agent β Writes personalized cold emails in English, Dutch, or Arabic referencing specific findings (e.g., "Your website loads in 8.2 seconds")
Discover β Analyze β Outreach β Track
Multilingual support: Search in English, Dutch, or Arabic. Outreach emails are generated in the selected language β including full Arabic support for businesses in the Middle East and North Africa.
Manage every lead through a drag-and-drop Kanban board β from discovery to won/lost.
| Requirement | Version | Why |
|---|---|---|
| Node.js | 20+ | Runtime for the API server and build tools |
| npm | 10+ | Package manager |
| Docker | Latest | Runs PostgreSQL, Redis, Lightpanda browser, and SearXNG |
| Git | Latest | Version control |
| AI API key | β | GLM or OpenAI-compatible API for email generation |
git clone https://github.com/MrFadiAi/FinX.git
cd FinX
npm installThis installs dependencies for both the backend API and the Next.js dashboard.
docker compose up -dThis starts four Docker containers:
| Service | Port | Purpose |
|---|---|---|
| PostgreSQL | 5432 | Database |
| Redis | 6379 | Background job queues |
| Lightpanda | 9222 | Lightweight browser for web scraping |
| SearXNG | 8080 | Meta search engine for web search (used by agents) |
Verify all are running:
docker compose psYou should see all four services with status Up.
cp .env.example .envOpen .env in your editor. At minimum, fill in these required values:
# REQUIRED β the app will crash without these
DATABASE_URL=postgresql://findx:findx@localhost:5432/findx
REDIS_URL=redis://localhost:6379
# REQUIRED β AI features (email generation, analysis, agent pipeline)
GLM_API_KEY=your-api-key-here
GLM_BASE_URL=https://open.bigmodel.cn/api/paas/v4
GLM_MODEL=glm-5.1Optional (for full functionality):
# Email sending β without this, emails are saved as drafts but not sent
RESEND_API_KEY=re_xxxxxxxxxxxxx
EMAIL_FROM=hello@yourdomain.com
# Web search β without SearXNG, agent web_search tool won't work
SEARXNG_URL=http://localhost:8080
# Dutch business sources β without these, discovery uses web search instead
KVK_API_KEY=your-kvk-key
GOOGLE_MAPS_API_KEY=your-google-keyCreate the database tables:
npm run db:migrateSeed the database with default pipeline stages and AI agents:
npm run db:seednpm run devThe API server starts on http://localhost:3001. Verify it's working:
curl http://localhost:3001/api/health
# Should return: {"status":"ok","timestamp":"..."}Open a new terminal and run:
npm run dev:webThe dashboard starts on http://localhost:3000. Open it in your browser.
- Discover β Finds businesses across multiple countries via local business registries (KVK, Companies House, Handelsregister, etc.) and Google Places APIs
- Analyze β Runs Lighthouse audits, detects tech stacks, scores websites 0-100
- Outreach β Generates personalized cold emails in English, Dutch, or Arabic using AI
- Track β Monitors email opens, replies, and bounces via Resend webhooks
Overview of your pipeline β total leads, analyzed, contacted, won. Score distribution chart.
Kanban board with your leads across stages: Discovered β Analyzing β Analyzed β Contacting β Responded β Qualified β Won/Lost. Click any lead card to see details. Drag leads between stages to move them through the pipeline.
Two tabs:
- Pipeline β Run the AI prospecting pipeline. Enter a search query like "restaurants in Amsterdam", pick a language (Nederlands or English), and hit Run. Three AI agents work in sequence: Research β Analysis β Outreach.
- Agents β View and configure each agent (identity, personality, tools, skills).
- AI Providers β Configure and switch between 8 AI providers (GLM, Anthropic, OpenAI, Ollama, DeepSeek, Groq, MiniMax, Kimi). Test connections and set a default.
- Email Providers β Connect Gmail (OAuth2), configure SMTP (e.g., Namecheap Private Email), or use Resend. Switch providers from the dashboard.
- Data Management β Clear all data, re-seed agents, import/export CSV.
Outreach emails can be generated in three languages:
| Language | Code | Style |
|---|---|---|
| English | en |
Professional English, British spelling |
| Dutch | nl |
Formal business Dutch (u/uw register), Dutch subject lines |
| Arabic | ar |
Professional Modern Standard Arabic, full RTL support |
Select the language from the dropdown on the Agents > Pipeline tab before running a pipeline. Default is English.
Switch between 8 AI providers from the dashboard β no code changes needed:
| Provider | Protocol | Notes |
|---|---|---|
| GLM / ZhipuAI | OpenAI | Default, well-tested |
| Anthropic | Messages API | Claude models |
| OpenAI | OpenAI | GPT models |
| Ollama | OpenAI | Local models, free |
| DeepSeek | OpenAI | Cost-effective |
| Groq | OpenAI | Fast inference |
| MiniMax | OpenAI | Chinese market |
| Kimi / Moonshot | OpenAI | Long context |
Configure API keys, base URLs, and models per provider. Test connections and set a default β all from the Settings page.
Send outreach emails through 3 different providers:
- Gmail β Full OAuth2 flow (authorize, auto-refresh tokens). Use your Gmail account.
- SMTP β Any SMTP server (Namecheap Private Email, Outlook, etc.). Pre-configured defaults for Namecheap.
- Resend β API-based email delivery.
Switch providers from the Settings page. Without any email provider configured, emails are saved as drafts.
Each agent has access to 21 registered tools:
| Tool | Purpose |
|---|---|
web_search |
Search the web via SearXNG |
scrape_page |
Scrape website content (HTML or text) |
check_website |
Check if a URL is live |
run_lighthouse |
Run Lighthouse performance audit |
detect_tech |
Detect website tech stack (Playwright) |
take_screenshot |
Capture website screenshot |
extract_emails |
Find email addresses on a page |
extract_social_links |
Find social media profiles |
check_ssl |
Check SSL/TLS certificate validity and expiry |
check_mx |
Verify email domain MX records |
check_mobile_friendly |
Score mobile responsiveness |
domain_age_check |
Check domain registration age (RDAP) |
get_place_details |
Fetch Google Business profile + reviews |
competitor_compare |
Find competitors via SearXNG |
kvk_search |
Search Dutch Chamber of Commerce |
google_places_search |
Search Google Places API |
save_lead |
Save business to database |
save_analysis |
Save website analysis results |
save_outreach |
Save outreach email draft |
render_template |
Render email template (EN/NL/AR) |
send_email |
Send an approved email |
Skills inject validation rules into agent prompts at runtime:
| Skill | Agent | Purpose |
|---|---|---|
| Dutch Email Quality | Outreach | Checks formal register consistency, anglicism detection, word limits |
| Outreach Specificity | Outreach | Requires minimum 2 specific data references per email |
| Analysis Completeness | Analysis | Validates required fields, numeric scores, prioritized recommendations |
Automatic lead scoring on a 0-100 scale:
- Data Completeness (0-30): business name, city, industry, address, KVK number
- Website Quality (0-40): has website, website analysis score
- Contactability (0-30): email, phone, valid MX records, social profiles
Leads are categorized as Cold (< 40), Warm (40-70), or Hot (> 70).
- Bulk Analyze β Queue analysis for up to 100 leads with websites
- Bulk Outreach β Queue outreach generation for up to 100 analyzed leads
- Bulk Status Update β Batch lead status transitions
- CSV Import β Import leads with auto-header detection (English, Dutch, snake_case)
- CSV Export β Export leads and outreaches (filtered, up to 5000 rows)
Generate branded PDF reports for any analysis β includes score breakdown, findings, opportunities, and recommendations. Available via /api/analyses/:id/report.
FindX/
βββ src/ # Backend (Fastify + TypeScript, ESM)
β βββ server.ts # API entry point (port 3001)
β βββ routes/index.ts # All API endpoints
β βββ agents/ # AI agent pipeline system
β β βββ core/ # Agent registry, runner, tools, skills, prompts
β β β βββ skills/ # 3 validated agent skills
β β β βββ tools/ # 21 registered tools
β β βββ orchestrator/ # Pipeline orchestrator (Research β Analysis β Outreach)
β βββ lib/
β β βββ db/client.ts # Prisma database client
β β βββ ai/ # Multi-provider AI system
β β β βββ providers/ # 8 providers, 2 protocol adapters, registry
β β βββ email/ # Multi-provider email system
β β β βββ providers/ # Gmail (OAuth2), SMTP, Resend
β β βββ browser/client.ts # Lightpanda + Playwright browser
β β βββ queue/index.ts # BullMQ queue helpers
β βββ modules/
β β βββ discovery/ # Lead discovery (KVK + Google Places)
β β βββ analyzer/ # Website analysis (Lighthouse + AI + PDF reports)
β β βββ outreach/ # AI email generation (21 templates Γ 3 languages)
β β βββ pipeline/ # Pipeline stage management
β β βββ leads/ # Lead scoring, bulk actions, CSV import/export
β β βββ import-export/ # CSV parsing utilities
β βββ workers/ # BullMQ background job workers
β βββ queues.ts # 6 named queues
β βββ agent-worker.ts # Agent pipeline worker
β βββ discovery.ts # Discovery worker
β βββ analysis.ts # Analysis worker
β βββ outreach.ts # Outreach worker
βββ web/ # Frontend (Next.js 15, React 19, Tailwind 4)
β βββ app/
β β βββ page.tsx # Dashboard
β β βββ agents/page.tsx # Agent pipeline runner + management
β β βββ agents/[name]/page.tsx # Agent detail (editable config + skills)
β β βββ pipeline/page.tsx # Kanban board (drag-and-drop)
β β βββ settings/page.tsx # AI providers + email providers + data management
β βββ components/ # React components (kanban, leads, analysis, etc.)
β βββ lib/
β βββ api.ts # API client
β βββ types.ts # TypeScript types
β βββ hooks/ # Custom hooks (usePolling)
βββ agents/ # Agent identity files (source of truth)
β βββ research/ # IDENTITY.md, SOUL.md, TOOLS.md
β βββ analysis/ # IDENTITY.md, SOUL.md, TOOLS.md
β βββ outreach/ # IDENTITY.md, SOUL.md, TOOLS.md
βββ prisma/
β βββ schema.prisma # Database schema (13 models)
β βββ seed.ts # Seed data
β βββ migrations/ # Database migrations
βββ docker-compose.yml # PostgreSQL + Redis + Lightpanda + SearXNG
βββ searxng/settings.yml # SearXNG configuration
βββ .env.example # Environment variables template
βββ CLAUDE.md # AI coding assistant instructions
βββ package.json # Workspace root
| Layer | Technology |
|---|---|
| API | Fastify (Node.js, TypeScript, ESM) |
| Database | PostgreSQL 16 via Prisma ORM |
| Queues | BullMQ (Redis-backed) |
| AI | Multi-provider: GLM, Anthropic, OpenAI, Ollama, DeepSeek, Groq, MiniMax, Kimi |
| Multi-provider: Gmail (OAuth2), SMTP (Nodemailer), Resend | |
| Browser | Lightpanda (CDP, low RAM) + Playwright Chromium fallback |
| Search | SearXNG (self-hosted meta search, 70+ engines) |
| Frontend | Next.js 15, React 19, Tailwind 4 |
| Scraping | Cheerio + Playwright |
| Business Data | KVK Open API, Google Places API |
| Audits | Lighthouse |
| Reports | PDFKit (branded PDF reports) |
| Command | Description |
|---|---|
npm run dev |
Start API with hot reload (tsx watch, port 3001) |
npm run dev:web |
Start Next.js dashboard (port 3000) |
npm run build |
TypeScript compile check |
npm run build:web |
Build Next.js for production |
npm run db:migrate |
Run Prisma migrations (dev) |
npm run db:migrate:deploy |
Deploy migrations (production) |
npm run db:seed |
Seed pipeline stages + 3 agents |
npm run db:studio |
Open Prisma Studio (DB GUI) |
npm run test |
Run tests (Vitest) |
npm run test:watch |
Run tests in watch mode |
npm run typecheck |
TypeScript type checking |
All endpoints are under /api/.
| Method | Path | Description |
|---|---|---|
| POST | /api/leads/discover |
Trigger lead discovery job |
| POST | /api/leads |
Create a lead manually |
| GET | /api/leads |
List leads (paginated, filterable) |
| GET | /api/leads/:id |
Get lead with analyses and outreaches |
| PATCH | /api/leads/:id |
Update lead fields/status |
| POST | /api/leads/bulk/analyze |
Bulk analyze leads |
| POST | /api/leads/bulk/outreach |
Bulk generate outreach |
| POST | /api/leads/import |
Import leads from CSV |
| GET | /api/leads/export |
Export leads as CSV |
| Method | Path | Description |
|---|---|---|
| POST | /api/leads/:id/analyze |
Trigger website analysis |
| GET | /api/leads/:id/analyses |
List analyses for a lead |
| GET | /api/analyses/:id |
Get single analysis |
| GET | /api/analyses/:id/report |
Download PDF report |
| Method | Path | Description |
|---|---|---|
| POST | /api/leads/:id/outreach/generate |
Generate AI email |
| POST | /api/leads/:id/outreach/send |
Send an approved email |
| GET | /api/leads/:id/outreaches |
Get outreach history |
| GET | /api/outreaches |
List all outreaches (filterable) |
| GET | /api/outreaches/:id |
Get single outreach |
| PATCH | /api/outreaches/:id |
Update draft or approve |
| GET | /api/outreach/rate-limit |
Check daily send limit |
| Method | Path | Description |
|---|---|---|
| POST | /api/agents/run |
Run pipeline (query, language, maxResults) |
| GET | /api/agents/runs |
List pipeline runs |
| GET | /api/agents/runs/:id |
Get run details with leads |
| GET | /api/agents/runs/:id/emails |
Get email drafts from a run |
| POST | /api/agents/runs/:id/cancel |
Cancel a running pipeline |
| GET | /api/agents |
List all agents |
| GET | /api/agents/name/:name |
Get agent by name |
| PATCH | /api/agents/name/:name |
Update agent config |
| POST | /api/agents/seed |
Re-seed default agents |
| GET | /api/agents/tools |
List all 21 registered tools |
| GET | /api/agents/logs |
View agent execution logs |
| GET | /api/agents/:id/skills |
List agent skills |
| POST | /api/agents/:id/skills |
Create agent skill |
| PATCH | /api/agents/:id/skills/:skillId |
Update agent skill |
| DELETE | /api/agents/:id/skills/:skillId |
Delete agent skill |
| Method | Path | Description |
|---|---|---|
| GET | /api/ai-providers |
List all configured providers |
| POST | /api/ai-providers |
Add a new provider |
| PATCH | /api/ai-providers/:id |
Update provider config |
| DELETE | /api/ai-providers/:id |
Remove a provider |
| POST | /api/ai-providers/:id/test |
Test provider connection |
| POST | /api/ai-providers/:id/default |
Set as default provider |
| GET | /api/ai-providers/defaults |
Get provider defaults |
| Method | Path | Description |
|---|---|---|
| GET | /api/email/provider |
Get current email provider status |
| GET | /api/email/gmail/auth-url |
Get Gmail OAuth2 authorization URL |
| GET | /api/email/gmail/callback |
Gmail OAuth2 callback (exchange code for tokens) |
| DELETE | /api/email/gmail |
Disconnect Gmail |
| GET | /api/email/smtp |
Get SMTP config |
| POST | /api/email/smtp |
Save SMTP config |
| POST | /api/email/smtp/test |
Send test email via SMTP |
| GET | /api/email/settings |
Get email settings (default provider) |
| POST | /api/email/settings |
Set email settings (default provider) |
| Method | Path | Description |
|---|---|---|
| GET | /api/health |
Health check |
| GET | /api/pipeline |
Pipeline stages with lead counts |
| GET | /api/dashboard/stats |
Dashboard metrics + score distribution |
| POST | /api/webhooks/resend |
Resend email tracking (open/reply/bounce) |
# Run the full agent pipeline (English emails)
curl -X POST http://localhost:3001/api/agents/run \
-H "Content-Type: application/json" \
-d '{"query":"restaurants in Amsterdam","language":"en","maxResults":10}'
# Run with Dutch emails
curl -X POST http://localhost:3001/api/agents/run \
-H "Content-Type: application/json" \
-d '{"query":"tandartsen in Rotterdam","language":"nl","maxResults":5}'
# Run with Arabic emails (e.g., businesses in Dubai)
curl -X POST http://localhost:3001/api/agents/run \
-H "Content-Type: application/json" \
-d '{"query":"restaurants in Dubai","language":"ar","maxResults":5}'
# Analyze a single lead
curl -X POST http://localhost:3001/api/leads/{leadId}/analyze \
-H "Content-Type: application/json" \
-d '{"sync":true}'
# Generate and send an outreach email
curl -X POST http://localhost:3001/api/leads/{leadId}/outreach/generate \
-H "Content-Type: application/json" \
-d '{"sync":true,"tone":"professional","language":"nl"}'13 Prisma models:
| Model | Description | Key Fields |
|---|---|---|
| Lead | Core business record | businessName, city, website, status, leadScore, kvkNumber, source |
| Analysis | Website audit results | score (0-100), findings, opportunities, techStack, socialPresence, competitors, serviceGaps, revenueImpact |
| Outreach | Email record | subject, body, tone, language, status, personalizedDetails |
| PipelineStage | Kanban columns | name, order |
| Agent | AI agent config | identityMd, soulMd, toolsMd, toolNames, model, pipelineOrder |
| AgentSkill | Agent validation rules | promptAdd, toolNames, sortOrder |
| AgentLog | Execution logs | phase, tokens, duration, output |
| AgentPipelineRun | Pipeline run record | query, status, leadsFound, leadsAnalyzed, emailsDrafted |
| AiProvider | AI provider config | type (8 enums), apiKey, baseUrl, model, isDefault |
| SmtpConfig | SMTP email config | host, port, user, fromEmail, fromName |
| EmailSetting | Email preferences | defaultProvider (gmail/smtp/resend) |
| EmailProviderToken | OAuth2 tokens | provider, accessToken, refreshToken, expiry |
Lead statuses: discovered β analyzing β analyzed β contacting β responded β qualified β won / lost
Outreach statuses: draft β pending_approval β approved β sent β opened / replied / bounced / failed
The core of FindX is a 3-phase AI agent pipeline with 21 tools and 3 validated skills:
-
Research Agent β Takes a search query (e.g., "restaurants in Amsterdam") and finds matching businesses across multiple countries using web search (SearXNG), local business registries (KVK, Companies House, Handelsregister, etc.), and Google Places. Saves them as leads with automatic deduplication.
-
Analysis Agent β For each lead with a website, runs Lighthouse audits, detects the tech stack, checks SSL, scores the website 0-100, checks mobile-friendliness, domain age, and identifies automation opportunities with revenue impact estimates. Generates branded PDF reports.
-
Outreach Agent β Reads analysis results and generates personalized cold emails in English (
en), Dutch (nl), or Arabic (ar) from 21 trilingual templates (7 categories x 3 languages). References specific findings (e.g., "Your website loads in 8.2 seconds"). Skills validate email quality before saving.
Agents are fully configurable through the dashboard β edit identity, personality, tools, skills, and even the AI model used per agent at /agents/[name].
The backend didn't shut down cleanly. Find and kill the process:
netstat -ano | grep ":3001" | grep LISTENING
# Then kill the PID
taskkill /F /PID <PID>Then restart: npm run dev
Same approach β find and kill the process on port 3000.
PostgreSQL might not be running:
docker compose ps # Check status
docker compose up -d # Start if stopped
docker compose restart postgres # Restart if stuckThe backend is likely down. Check:
curl http://localhost:3001/api/health # Backend health
curl http://localhost:3001/api/leads?pageSize=10 # Data checkdocker compose down # Stop everything
docker compose up -d # Start fresh
docker compose logs postgres # Check logs if issuesThe tsx watch hot reload sometimes misses edits. Kill and restart:
netstat -ano | grep ":3001" | grep LISTENING
taskkill /F /PID <PID>
npm run devIf FindX helped you, consider buying me a coffee:
Private β All rights reserved.

