Autonomous web research tool using parallel Claude agents with Ghost-hosted Postgres storage and a live Next.js dashboard.
web-research-labeler crawls the web for a given topic, stores results in a Postgres database, labels results with configurable schemas, and displays live progress in a dashboard.
Key features:
- Parallel Claude agents for research and labeling
- Ghost-managed Postgres database via
DATABASE_URL - Python CLI scripts for crawl and labeling
- Next.js dashboard for live monitoring
- Raw SQL + lightweight
pgandpsycopg2usage
Tech stack: Python, TypeScript, CSS | Next.js + React | PostgreSQL via raw SQL (pg, psycopg2) | Ghost CLI for DB provisioning | Anthropic Claude API with web_search_20260209 tool
scripts/setup_db.py— create Postgres tablescrawl.py— research web results using Claude agentslabel.py— label unlabeled results using Claude agentsexport.py— export results and labels to JSONstart_dashboard.sh— launch the dashboardrequirements.txt— Python dependencies
dashboard/app/— Next.js dashboard UI and API routeslib/db.ts— shared database connection logicpackage.json— dashboard dependencies and scripts
PLAN.md— implementation plan and architecture notesCLAUDE.md— project-specific agent/research notes
- Install Ghost CLI and create a Ghost database:
curl -fsSL https://install.ghost.build | sh
ghost login
ghost create --name web-research
ghost connect <db-id>- Copy
.env.exampleto.envand set:
ANTHROPIC_API_KEY=sk-ant-...
DATABASE_URL=postgresql://... # from ghost connect
- Install Python dependencies and create the DB schema:
python -m venv .venv
source .venv/bin/activate
pip install -r scripts/requirements.txt
python scripts/setup_db.py- Install dashboard dependencies:
cd dashboard
npm installpython scripts/crawl.py --topic "coral reef restoration" --agents 3 --max-results 50Each agent researches the topic from a different angle and inserts results into the results table.
bash scripts/start_dashboard.shThen open http://localhost:3000 to watch live stats, agent activity, and collected results.
python scripts/label.py --schema "relevance:high/medium/low, type:article/study/news" --agents 3This command classifies unlabeled results and stores structured labels in the labels table.
python scripts/export.py # all results → export.json
python scripts/export.py --labeled-only -o research.json # only labeled
python scripts/export.py --topic "coral reef restoration" # filter by topicExports results and labels to a JSON file for downstream use.
-
crawl.py- Uses parallel Claude agents with the
web_search_20260209tool - Stores extracted
{url, title, content}results in Postgres - Logs agent progress and errors in
agent_logs - Uses isolated DB connections per agent for safe concurrency
- Uses parallel Claude agents with the
-
label.py- Fetches unlabeled results via
FOR UPDATE SKIP LOCKED - Prompts Claude to classify results against a schema
- Records labels and marks results as labeled
- Fetches unlabeled results via
dashboard/app/page.tsxpolls API endpoints for live updatesdashboard/app/api/stats/route.tssummarizes counts and recent logsdashboard/app/api/results/route.tsreturns the latest results and labelsdashboard/lib/db.tsprovides a sharedpg.PoolusingDATABASE_URL
- Confirm tables exist with:
python scripts/setup_db.pyghost psql <db-id>
- Run crawl:
python scripts/crawl.py --topic "coral reef restoration" --agents 2 --max-results 10
- Launch the dashboard:
bash scripts/start_dashboard.sh
- Label results:
python scripts/label.py --schema "relevance:high/medium/low, type:article/study/news" --agents 2
- Export results:
python scripts/export.py --labeled-only -o research.json